4. Narzędzia developerskie

Wyzwania:

  • dowiesz się, z czego będzie się składać nasze środowisko pracy,
  • zaczniesz pracować z systemem kontroli wersji,
  • nauczysz się automatyzować czynności związane z projektem.

4.1. Wprowadzenie

Do tej pory pracowaliśmy głównie w edytorze Kodilli, dzięki czemu mogliśmy bez przeszkód rozpocząć naukę. Nadszedł jednak czas, by pójść krok dalej i poznać narzędzia, których używają profesjonalni programiści. W tym module omówimy i stworzymy od podstaw nowe lokalne środowisko developerskie, dzięki któremu Twoja praca będzie przebiegała sprawniej i ustrzeżesz się potencjalnych problemów.

Czym jest środowisko developerskie?

Środowiskiem developerskim nazywamy zestaw narzędzi używanych przez programistę do pracy nad projektem. W podstawowym zakresie środowisko pracy będzie składać się z kilku elementów, takich jak katalog roboczy, edytor kodu, system kontroli wersji czy manager pakietów (NPM).

A co oznacza słowo "lokalne" w tym kontekście? To bardzo proste – znaczy to, że wszystkie niezbędne narzędzia i pliki znajdują się na Twoim komputerze, a nie na zewnętrznych serwerach.

Po co nam środowisko developerskie?

Możesz w tym momencie zastanawiać się, po co w ogóle tworzyć lokalne środowisko developerskie, skoro internet jest pełen gotowych edytorów online, które potrafią kompilować pliki preprocesorów (np. .scss), automatycznie odświeżać podgląd, i tak dalej. Powodów jest wiele, tu wymienimy kilka podstawowych:

  • możliwość pracy bez dostępu do internetu – w przypadku awarii sieci, nie tracisz całkowicie możliwości pracy nad projektem. Większość funkcjonalności jest dostępna offline, więc brak internetu nie przeszkadza Ci w rozwijaniu kodu.
  • łatwiejsza obsługa większych projektów – edytory online mają swoje ograniczenia. Bardziej rozbudowane projekty (którymi już niedługo będziesz się zajmować!) zwykle wymagają dodatkowej konfiguracji lub specyficznej struktury katalogów, której edytory nie wspierają.
  • swoboda wyboru i konfiguracji narzędzi – tworząc własne środowisko, masz możliwość wyboru najwygodniejszych dla siebie narzędzi i dostosowania ich do swoich potrzeb. W tym module pokażemy pewien ich zestaw, ale nic nie stoi na przeszkodzie, aby wraz z rozwijaniem się jako developer modyfikować swoje środowisko pracy i dokładać do niego nowe elementy.
  • połączenie z systemem kontroli wersji – bardzo ważna sprawa, dzięki której zabezpieczasz się przed utratą swojego kodu w przypadku awarii komputera oraz przygotowujesz się do pracy jako profesjonalny developer w zespole innych programistów.

Poza tym, kiedy zaczniesz pracować w IT, przekonasz się, że w każdej firmie używa się lokalnego środowiska developerskiego. Tak więc umiejętność jego konfiguracji i obsługi jest niezbędna każdemu programiście! Znajomość narzędzi opisanych w tym module jest bardzo często wymagana przy rekrutacji na stanowiska developerskie.

Uwaga: niektóre czynności opisane w tym module mogą wydać Ci się żmudne. Są one jednak konieczne, by prawidłowo skonfigurować środowisko i nauczyć się w nim poruszać, co bardzo zaprocentuje już w niedalekiej przyszłości. Nie zniechęcaj się!

4.2. Elementy środowiska developerskiego

Omówimy sobie teraz podstawowe składowe lokalnego środowiska developerskiego. W kolejnym submodule zajmiemy się bardziej zaawansowanym narzędziem, czyli managerem pakietów.

Katalog roboczy

Zacznijmy od miejsca na dysku Twojego komputera, gdzie będziesz zapisywać swoje projekty. Warto założyć katalog np. o nazwie Kodilla, który może się znajdować nawet bezpośrednio na dysku (najlepiej innym niż ten, na którym trzymasz system operacyjny). W tym katalogu Kodilla będziesz tworzyć nowy katalog dla każdego zadania lub projektu.

image

To dość podstawowa sprawa i być może już masz założony katalog na projekty – jeśli tak, to świetnie! Warto pamiętać o trzymaniu porządku na dysku. Dzięki temu będziesz zawsze wiedzieć, gdzie szukać swoich projektów.

Struktura katalogów w projekcie

Również w katalogu projektu warto dbać o porządek. Z tego względu przeważnie grupuje się pliki w podkatalogach. Ta struktura może zależeć od charakterystyki projektu, ale najprostszym przykładem jest założenie podkatalogów:

  • sass/ - w którym będziemy tworzyć i edytować pliki *.scss,
  • css/ - w nim znajdują się wyłącznie pliki wygenerowane przez Sassa,
  • vendor/ - jest przeznaczony na pliki bibliotek (np. Bootstrap), których nie edytujemy,
  • images/ - w którym znajdują się obrazki, z których korzysta nasz projekt,
  • js/ - w nim już niedługo będziemy tworzyć pliki z kodem JavaScript.

Uwaga: w pierwszych zadaniach w tym module będziesz pisać tylko w CSS. Później dowiesz się, jak lokalnie kompilować pliki .scss do .css i od tego momentu będziemy używać formatu .scss.

Kolejnym elementem trzymania porządku w projekcie jest zasada, że w katalogu vendor mają znajdować się jedynie pliki bibliotek, które nie zostały przez nas zmienione. Przykładem mogą tu być wszystkie pliki Bootstrapa, ale również np. pliki .js i .css używanych pluginów (np. karuzela). Dzięki temu, w przypadku potrzeby aktualizacji np. Bootstrapa do nowszej wersji, nie będzie wątpliwości, czy te pliki zostały w jakiś sposób zmienione. Jeśli potrzebujemy edytować np. plik .css jakiejś biblioteki, wtedy zmieniamy jego rozszerzenie na .scss i przenosimy go do katalogu sass.

Dzięki takiej strukturze nasz katalog projektu będzie znacznie mniej "zagracony" i łatwiej nam będzie odnaleźć w nim potrzebne pliki.

Edytor kodu

Podstawowym narzędziem pracy każdego developera jest edytor kodu. Oczywiście, można pisać kod przy pomocy zwykłego windowsowego Notatnika, ale dedykowane edytory kodu znacznie ułatwiają pracę.

Jeśli jeszcze nie masz zainstalowanego żadnego edytora kodu, polecamy bezpłatny edytor Atom.

Obowiązkową funkcjonalnością każdego edytora kodu jest możliwość kolorowania składni. Dzięki temu dużo łatwiej czyta się kod, co pomaga unikać błędów. Jest to jednak tylko jedno z wielu usprawnień, w jakie może być wyposażony edytor kodu. Do najczęstszych z nich należą:

  • podświetlanie błędów składni,
  • obsługa tzw. snippetów, czyli szybkiego wstawiania często powtarzających się fragmentów kodu,
  • używanie wielu kursorów, dzięki czemu możemy modyfikować jednocześnie kod w wielu linijkach (np. dodanie linków do wszystkich elementów listy),
  • przeglądanie katalogu projektu i obsługa plików (tworzenie, usuwanie, zmiana nazwy itd.) z poziomu edytora.

Atom ma wbudowane niektóre z powyższych funkcjonalności, a mnóstwo innych można dodać za pomocą wtyczek. Dostępne wtyczki możesz przejrzeć na oficjalnej liście, a zainstalować je klikając w edytorze File > Settings > Install:

image

Jeśli nie będzie Ci odpowiadał Atom, jest wiele innych edytorów, z których możesz skorzystać. Kilka przykładów popularnych edytorów kodu:

Terminal

Być może znasz już określenia "terminal", "konsola" lub "linia poleceń". Większości początkujących web developerów wydaje się, że to jest coś strasznego, ale tak naprawdę można szybko nabrać wprawy w podstawowym korzystaniu z terminala.

Do obsługi komputera zwykle wykorzystujemy interfejs graficzny (GUI - Graphical User Interface), natomiast terminal jest interfejsem tekstowym (CLI - Command Line Interface). Co oznaczają te pojęcia?

Interfejs graficzny to na przykład eksplorator plików:

image

W interfejsie graficzny wykorzystuje się zwykle:

  • kilka równolegle dostępnych informacji, np. lista plików w głównym oknie, lista katalogów w bocznej kolumnie, pasek adresu pokazujący obecnie przeglądaną lokalizację, etc.,
  • wiele guzików i menu, pozwalających na wywołanie różnych akcji, np. zmianę nazwy pliku czy uruchomienie pliku w wybranym programie,
  • akcje obsługiwane za pomocą kursora myszy, np. przenoszenie plików do innego katalogu.

Interfejs tekstowy różni się od graficznego m.in. tym, że:

  • akcje wykonuje się za pomocą komend tekstowych,
  • wszystkie wyświetlane komunikaty i informacje są prezentowane za pomocą tekstu,
  • informacje np. o liście plików w katalogu nie są cały czas wyświetlone, tylko pokazywane jednorazowo po wykonaniu komendy tekstowej.

Terminal jest świetnym przykładem interfejsu tekstowego. Na poniższej ilustracji możesz zobaczyć, jak w terminalu wygląda wyświetlenie zawartości tego samego katalogu, który widzieliśmy w przeglądarce plików powyżej.

image

Poniżej możesz zobaczyć porównanie CLI i GUI przy wyświetleniu zawartości katalogu, przejściu do podkatalogu i zmianie widoku na bardziej szczegółowy. Po lewej stronie wykonujemy te operacje w terminalu, a z prawej strony w przeglądarce plików.

image

Początkowo terminal może nie wyglądać na najwygodniejsze rozwiązanie na świecie, ale uwierz, że wraz ze swoim rozwojem jako programista będziesz coraz bardziej się z nim oswajać i z czasem stanie się on dla Ciebie niezastąpiony.

Jeśli nie masz wprawy w korzystaniu z terminala, możesz zapoznać się z przygotowanym przez nas poradnikiem obsługi linii komend.

Repozytorium

Aby pliki naszego projektu były dostępne dla innych (np. aby mogli je pobrać i otworzyć projekt lokalnie), musimy trzymać je gdzieś poza naszym komputerem. Jednym z takich miejsc są repozytoria, czyli platformy, gdzie można przechowywać nie tylko aktualne pliki, ale również pełną historię zmian w projekcie. Zamiast więc wysyłać sobie co chwilę kod mailem po wprowadzanych zmianach, wystarczy udostępnić go w repozytorium, by każdy członek zespołu miał dostęp do najbardziej aktualnej wersji.

Przechowywanie kodu "na zewnątrz" jest również istotne z powodu bezpieczeństwa — repozytorium pozwoli nam zabezpieczyć się przed utratą kodu w przypadku np. awarii naszego komputera.

W repozytorium można również tworzyć gałęzie (ang. branch) od głównego projektu (ang. master), czyli takie "kopie robocze" służące do tego, aby nie modyfikować głównej struktury strony czy aplikacji od razu, tylko przygotować konkretną zmianę tak dobrze, jak to tylko możliwe, a następnie połączyć ją z aktualną i działającą wersją.

System kontroli wersji

System kontroli wersji to nic innego, jak zestaw narzędzi do obsługi repozytoriów. Zakres jego funkcjonalności to m.in.:

  • wysyłanie naszego kodu do zdalnego repozytorium,
  • pobieranie kodu z dowolnego miejsca na świecie (o ile mamy dostęp do zdalnego repozytorium),
  • tworzenie nowych gałęzi,
  • dowiązywanie gałęzi do głównego projektu bądź dowiązywanie gałęzi naszego kolegi do swojej gałęzi, aby połączyć wytworzone przez nas funkcje.

System kontroli wersji jest bardzo często używany przez programistów, ponieważ daje m.in. następujące korzyści:

  • znikome ryzyko utraty plików np. w konsekwencji awarii dysku,
  • sprawna współpraca z innymi web developerami, nawet jeśli pracujecie w tym samym pliku,
  • utrzymywanie porządku przy równoczesnym budowaniu kilku funkcjonalności,
  • dokumentacja przebiegu prac na wypadek potrzeby powrotu do wcześniejszej wersji,
  • komunikacja z innymi developerami poprzez czytelne opisy wprowadzanych zmian,
  • przy bardziej skomplikowanych konfiguracjach po stronie serwera może też automatyzować niektóre procesy.

W wielkim skrócie, działanie systemu kontroli wersji polega na zapisywaniu kolejnych wersji projektu. Na przykład po dodaniu nawigacji strony, możesz za pomocą specjalnej komendy (ale o tym później) zapisać aktualną wersję projektu. W tytule tej wersji podajemy, co się zmieniło względem poprzedniej wersji.

Git

Dzięki temu łatwo będzie znaleźć tę zmianę i np. sprawdzić kto ją wykonał. Będziesz mieć również możliwość przywrócenia wcześniejszej wersji projektu, jeśli zajdzie taka potrzeba.

Systemy kontroli wersji bardzo dobrze też radzą sobie z łączeniem zmian wprowadzanych przez kilku web developerów. Wtedy praca zespołowa nie będzie już wymagała ręcznego łączenia zmian w kodzie.

Git

Obecnie najpopularniejszym systemem kontroli wersji jest Git. Właśnie z Gita będziemy korzystać od tego modułu, dzięki czemu sprawniej będzie przebiegać Twoja współpraca z mentorem.

Trzy słowa podsumowania

Jak widzisz, środowisko developerskie jest niczym innym, jak zestawem odpowiednio dobranych narzędzi. Jak już wspominaliśmy, ich dobór zależy od preferencji programisty lub całego zespołu, oraz w niektórych przypadkach od specyfiki projektu. Celem jest ułatwienie pracy programiście tak, by mógł skupić się na tym, co najważniejsze, czyli programowaniu.

4.3. Git – podstawy

Jeszcze nie tak dawno temu każdy developer pracujący nad projektem zapisywał kod lokalnie. Później, w celu połączenia zmian wykonanych przez wszystkich członków zespołu, należało porównywać pliki linijka po linijce – była to żmudna praca, obarczona wielkim ryzykiem błędów. A prawdziwe schody zaczynały się, gdy trzeba było wrócić do poprzedniej wersji danego pliku...

Jak już jednak wiesz, dzisiaj z pomocą przychodzi nam Git – system kontroli wersji obsługiwany najczęściej z poziomu wiersza poleceń. Pozwoli nam na zapisywanie kolejnych wersji projektu, które od teraz będziemy nazywali commitami. Innymi słowy, każda zmiana w projekcie, którą wrzucisz do repozytorium, będzie właśnie commitem. Na początku nauczymy się pracy na repozytorium lokalnym (na Twoim komputerze), a potem połączymy się z repozytorium zdalnym, by móc udostępniać pliki innym developerom (np. Mentorowi).

Każdy commit zapisuje wyłącznie zmiany względem poprzedniej wersji (czyli poprzedniego commita), dzięki czemu pliki, które nie uległy zmianie, nie są wielokrotnie zapisywane. Pozwala to na utrzymywanie możliwie małego rozmiaru repozytorium, a przez to również jego szybkie działanie. Nie musisz jednak martwić się jak z takich zapisów zmian odtworzyć cały projekt – tym będzie się zajmował Git.

Git to bardzo obszerny temat – poznanie go w całości i poczucie się całkowicie swobodnie we wszystkich zastosowaniach wymaga dużo czasu i praktyki. W tym submodule zapoznamy Cię z podstawowymi komendami, niezbędnymi do samodzielnej pracy z repozytorium. Bardziej zaawansowane przykłady zastosowania znajdziesz w przystępnym i zabawnym Poradniku Gita oraz w materiałach podlikowanych w ostatnim submodule, a wprawy nabierzesz w prawdziwej pracy wraz z innymi developerami.

Obejrzyj również nasze tutoriale o Gicie:

Instalacja Gita

Aby móc korzystać z Gita, musimy go najpierw zainstalować. Poniżej znajdziesz instrukcje dla poszczególnych systemów operacyjnych.

Informacja dla użytkowników systemu Windows

Wraz z Gitem zostanie zainstalowany program Git Bash. Będziemy z niego korzystać, ponieważ istnieją znaczące różnice pomiędzy windowsową linią komend (cmd.exe) a terminalami w systemach macOS oraz Linux. Oczywiście, wszystkie czynności da się wykonać także w tej pierwszej, jednak znajomość terminala linuksowego jest bardziej przydatna, ponieważ większość serwerów działa w oparciu o Linuksa.

Git Bash emuluje konsolę linuksową i likwiduje te różnice. Zawsze, kiedy w niniejszym kursie będziemy wspominali o terminalu, będziemy mieć na myśli właśnie Git Basha, a nie windowsową linię komend (cmd.exe).

Aby otworzyć terminal, kliknij prawym przyciskiem myszy (PPM) w dowolnym miejscu na pulpicie lub w eksploratorze plików, a następnie z menu kontekstowego wybierz Git Bash Here. Jeżeli wybierzesz tę opcję, klikając PPM na folderze, terminal otworzy się bezpośrednio w tym katalogu.

Więcej szczegółów dotyczących obsługi terminala możesz znaleźć w poradniku obsługi linii komend.

Windows

  1. Jeżeli dzielisz komputer z kimś, kto mógłby zainstalować już Gita, to sprawdź, czy w menu Start masz program Git Bash — jeśli znajdziesz ten program, możesz pominąć instalację.
  2. Wejdź na stronę https://git-scm.com/downloads i kliknij link "Windows".
  3. Uruchom instalator po ukończeniu pobierania.
  4. Przejdź przez wszystkie kroki instalatora, pozostawiając domyślne ustawienia.

macOS

  1. Jeżeli dzielisz komputer z kimś, kto mógłby zainstalować już Gita, to sprawdź, czy jest on już zainstalowany. W tym celu:
    1. Otwórz terminal (znajdziesz go w katalogu Programy, w podkatalogu Narzędzia).
    2. Wpisz komendę git --version i wciśnij enter.
    3. Jeśli pojawi się numer wersji Gita, możesz pominąć instalację. Jeżeli nie, przejdź do następnego kroku.
  2. Wejdź na stronę https://git-scm.com/downloads i kliknij w link "Mac OS X".
  3. Uruchom instalator po ukończeniu pobierania.
  4. Przejdź przez wszystkie kroki instalatora, pozostawiając domyślne ustawienia.
  5. Po zakończeniu instalacji sprawdź ponownie, czy Git już działa (tak samo jak w pkt. 1).

Linux

  1. Jeżeli dzielisz komputer z kimś, kto mógłby zainstalować już Gita, to sprawdź, czy jest on już zainstalowany. W tym celu:
    1. Otwórz terminal.
    2. Wpisz komendę git --version i wciśnij enter.
    3. Jeśli pojawi się numer wersji Gita, możesz pominąć instalację.
  2. Wejdź na stronę https://git-scm.com/downloads i kliknij link "Linux/Unix".
  3. Znajdź instrukcję dla swojego systemu operacyjnego i wpisz w swoim terminalu komendę podaną na stronie.
    Pamiętaj, że w wielu dystrybucjach Linuksa podana komenda musi być wykonana z prawami administratora, czyli np. wpisując "sudo" przed wpisaniem komendy instalacyjnej.
  4. Po zakończeniu instalacji sprawdź ponownie, czy Git już działa (tak samo, jak w pkt. 1).

Podstawowa konfiguracja Gita

Przed rozpoczęciem pracy będziemy musieli skonfigurować kilka parametrów w Gicie. Wystarczy, że wykonamy te operacje raz, i będą działać dla wszystkich przyszłych projektów.

Najpierw zapiszemy naszą nazwę użytkownika oraz naszego maila. Jest to potrzebne, ponieważ każdy zapisywany commit będzie podpisany — dzięki temu w pracy zespołowej wiadomo kto jest autorem danej zmiany. Jeżeli tego nie zrobimy, przy próbie zapisania commita Git odpowie nam komunikatem "Please tell me who you are".

Konfiguracja danych użytkownika zajmie tylko chwilę:

  1. Otwórz terminal (nie musisz się przejmować, na jaki katalog aktualnie wskazuje terminal, ponieważ będziemy definiować globalne ustawienia Gita).
  2. Wpisz poniższą komendę, podając swoje imię i nazwisko zamiast przykładowego: git config --global user.name "Jan Kowalski".
  3. Następnie wpisz kolejną komendę, oczywiście ze swoim adresem email: git config --global user.email "jan.kowalski@example.com".
  4. Możesz sprawdzić wszystkie globalne ustawienia Gita za pomocą komendy git config --global -l.
image

Teraz zajmiemy się jeszcze jedną komendą, która utworzy nam tzw. alias. Jest to po prostu skrót uruchamiający tę długą komendę:

git log --graph --decorate --pretty=oneline --abbrev-commit

za pomocą krótkiego aliasu: git tree.

Tworzenie aliasów nie jest konieczne do posługiwania się Gitem. Przyda nam się jednak, ponieważ bardzo często będziemy korzystać z tej komendy. W późniejszym rozdziale zobaczysz, jak działa ta komenda, oraz dlaczego jest nam potrzebna.

Wykonaj poniższe kroki, aby zapisać alias git tree:

  1. wróć do terminala,
  2. wpisz komendę git config --global alias.tree "log --graph --decorate --pretty=oneline --abbrev-commit",
  3. tak jak poprzednio, możesz sprawdzić wszystkie globalne ustawienia Gita za pomocą komendy git config --global -l.
image

Potrzebujemy zapisać jeszcze jedno ustawienie. Wpisz do terminala komendę git config --global push.default simple i zatwierdź enterem. Jeśli go nie zapiszemy, nie wpłynie to na działanie Gita, ale przy każdym wykonaniu komendy git push (o której dowiesz się w późniejszym submodule) zostanie wyświetlony długi komunikat na ten temat.

Inicjalizacja repozytorium

Pierwszą rzeczą, którą wykonamy, będzie zainicjowanie Gita w projekcie. Ta operacja doda do naszego projektu nowy folder .git, w którym będą przechowywane informacje o repozytorium.

Aby zainicjować lokalne repozytorium Gita, utwórz w katalogu roboczym nowy folder z projektem. Na potrzeby tego ćwiczenia nazwij go nauka-gita. Otwórz terminal w tym folderze i wykonaj komendę:

git init

Jeśli wszystko poszło sprawnie, Twój terminal powinien wyglądać podobnie do poniższej ilustracji:

image

Zwróć przy okazji uwagę, jak bez wychodzenia z terminala i odrywania rąk od klawiatury można tworzyć nowe foldery (komenda mkdir) i przemieszczać się między katalogami (komenda cd).

Nie zdziw się, jeśli nie będziesz widzieć stworzonego katalogu .git – jest on domyślnie ukryty. W konsoli można wyświetlić wszystkie (w tym ukryte) pliki i katalogi za pomocą komendy ls -a.

Jeśli pojawił się jakiś błąd, przeczytaj jego treść i spróbuj zrozumieć, co spowodowało błąd, a jeśli nadal nie będziesz wiedzieć, jak sobie z nim poradzić, wpisz treść błędu w wyszukiwarkę Google. Dopiero kiedy to nie pomoże, zwróć się o pomoc w komunikatorze na grupie #help-web-tools.

Inicjujemy Gita tylko raz w danym projekcie

Pamiętaj, że najczęściej będziesz inicjować repozytorium tylko kiedy rozpoczynasz nowy projekt, a konkretniej kiedy nie było jeszcze repozytorium dla tego projektu.

Jeśli dołączasz do istniejącego projektu, zamiast inicjowania repozytorium będziesz je klonować, o czym więcej przeczytasz w rozdziale "Alternatywa do podłączania — klonowanie repozytorium" w tym module.

Pierwsze commity

Commit zapisuje zmiany w plikach względem poprzedniego commita, co oznacza, że nadpisywane są tylko te pliki, które uległy modyfikacji, a nie całe repozytorium. Oczywiście w przypadku dodawania nowego pliku zmianą jest cały plik, więc zostanie zapisany w całości.

Wróć teraz do okna terminala. Jeśli nie masz go otwartego, otwórz terminal i przejdź do katalogu projektu. Następnie wykonaj komendę git status.

image

Komenda ta wyświetla nam aktualny stan repozytorium:

  • on branch master - informuje nas, na którym branchu (odgałęzieniu) projektu się znajdujemy,
  • Initial commit - mówi nam o tym, że w repozytorium nie zapisano jeszcze żadnego commita,
  • nothing to commit - oznacza, że na razie nie ma żadnych plików, które mogłyby być zapisane w commicie.

Stwórz teraz plik index.html z przykładową zawartością (możesz wykorzystać kod z któregoś z wcześniejszych zadań) w katalogu projektu i ponownie wykonaj komendę git status.

image

Tym razem komunikat informuje nas o "untracked files", czyli plikach, które nie są jeszcze dodane do indeksu. Index możesz wyobrazić sobie jako poczekalnię, gdzie znajdują się pliki oczekujące na commit. Innymi słowy, "untracked files" to pliki, które nie były jeszcze zapisane w żadnym commicie.

Czytanie komunikatów

Zwróć uwagę, że na obrazku powyżej Git w nawiasie podpowiedział nam, w jaki sposób dodać pliki do indeksu. Podobnie potrafi on zasugerować nam, co mogliśmy mieć na myśli, jeżeli wpiszemy błędną komendę:

image

Warto dokładnie czytać komunikaty pojawiające się w odpowiedzi na nasze komendy! Szczególnie w przypadku problemów może okazać się, że Git ma dla nas propozycję rozwiązania.

Kiedy mamy już plik, który chcemy zapisać w commicie, możemy przejść do przygotowania commita.

Możesz wyobrazić sobie to jako składanie zamówienia w sklepie internetowym — najpierw dodajesz produkty do koszyka, a dopiero potem zatwierdzasz zamówienie.

Jak wcześniej podpowiadał nam Git, do takiego przygotowania pliku (ang. staging) służy komenda git add, w której podajemy nazwę pliku dodawanego do indeksu. Wykonaj teraz w terminalu komendę git add index.html. Nie zwraca ona żadnego komunikatu, więc po niej wykonaj znów git status, aby zobaczyć, co się zmieniło.

image

Teraz możemy już zapisać nowy commit za pomocą komendy git commit -m "Add index.html".

image

W tej komendzie flaga -m oznacza, że po niej wpiszemy tytuł commita w cudzysłowie. Za chwilę wytłumaczymy, dlaczego wybraliśmy właśnie taki tytuł. Wcześniej jednak sprawdźmy, jak teraz wygląda nasze repozytorium.

Jeśli wykonasz teraz ponownie komendę git status, zobaczysz, że nie ma żadnych zmian do zapisania. Nic dziwnego, skoro właśnie zapisaliśmy wszystkie wprowadzone zmiany.

image

Jeżeli chcesz dodać do indeksu wszystkie nowe pliki, możesz użyć komendy git add . (czyli użyć kropki, zamiast wpisywać nazwę każdego pliku).

Dobre praktyki nazewnictwa commitów

Jak już wspomnieliśmy, każdy commit będzie miał swój opis. Ważne jest, aby te opisy były czytelne i spełniały funkcje komunikacji w zespole oraz dokumentacji przebiegu projektu. Dlatego przyjęły się standardy dobrego nazewnictwa commitów.

Zwięzłość

Przede wszystkim, tytuł commita (czyli to, co wpisywaliśmy w cudzysłowie w komendzie git commit) powinien krótko opisywać, co zostało zmienione względem wcześniejszej wersji. Staraj się nie przekroczyć 50 znaków w tytule commita.

Język

Standardem jest pisanie tytułów commitów w języku angielskim, rozpoczynając czasownikiem w czasie teraźniejszym prostym, zapisanym wielką literą. Dobrym pierwszym słowem tytułu commita może być więc "Add", "Remove", "Fix", lub "Change". Natomiast złym tytułem byłoby "Added index.html" czy "New file".

Czytelność

Unikaj ogólnikowych określeń typu "Add styles" czy "Fix bug". Staraj się pisać konkretniej, czyli np. "Add styles for footer" czy "Fix bug in slideshow".

Tagi

Zdarzają się sytuacje, w których przyda Ci się oznaczenie pewnego commita. Dla przykładu, kiedy wysyłasz podgląd strony swojemu klientowi albo testerowi, będziesz dalej pracować nad projektem, ale chcesz później wrócić do tego commita i przeglądać otrzymane uwagi patrząc na dokładnie tę samą wersję projektu.

W takiej sytuacji przydają się tagi. Dzięki nim możemy oznaczyć dowolny commit tagiem, po którym łatwo odnajdziemy ten commit. Dodajmy tag do naszego commita:

  1. Otwórz terminal i przejdź do katalogu swojego projektu.
  2. Wykonaj komendę git tag "v1".
  3. Ta komenda nie zwraca nam żadnych informacji, więc wykonaj komendę git tree, aby sprawdzić, co się zmieniło.
image

Jak widzisz na powyższej ilustracji, teraz w nawiasie oprócz oznaczenia "HEAD -> master" (które jest zawsze przy najnowszym commicie) widzimy również nasz nowy tag.

Dodawanie tagu do wcześniejszego commita

Powyższa komenda dodaje tag do najnowszego commita. Jeśli jednak zechcesz dodać tag do wcześniejszej wersji, możesz zrobić to używając identyfikatora commita, czyli ciągu znaków, który wyświetla się przy każdym commicie w odpowiedzi na komendę git tree.

Aby np. dodać tag przy commicie, który ma identyfikator e754f41, użyjesz komendy git tag "v1" e754f41.

Podsumowanie — przykład standardowego użycia

Zwykle w swojej pracy będziesz po kolei realizować zadania, na które podzielisz sobie pracę nad projektem. Jak już wspomnieliśmy, dobrą praktyką jest zapisywania commita po każdym wykonanym zadaniu.

Sposób podziału na zadania będzie zależał od Twoich potrzeb, rozmiaru zespołu, praktyk przyjętych w organizacji, etc. Możesz przyjąć podział na drobne zadania, np.:

  • dodanie HTML dla logo strony,
  • dodanie stylów dla logo strony,
  • dodanie HTML bannera strony,
  • ostylowanie bannera strony,
  • dodanie HTML głównej nawigacji,
  • ostylowanie głównej nawigacji,
  • etc.

Możesz też przyjąć inne podejście, w którym będziesz stosować nieco mniej szczegółowy podział. W takim wypadku punkty wymienione w powyższym przykładzie mogłyby stanowić jedno większe zadanie, np. "dodanie nagłówka strony".

W tym przykładzie posłużymy się jednak pierwszym podejściem, czyli będziemy zapisywać commit po każdym małym zadaniu. Przebieg pracy mógłby wyglądać następująco:

  1. założenie katalogu projektu,
  2. zainicjowanie Gita komendą git init,
  3. dodanie podstawowej struktury plików i katalogów, np. index.html, i css/style.css,
  4. git add . && git commit -m "Init project"
  5. dodanie struktury HTML w pliku index.html (doctype oraz elementy html, head, meta, title, link, body),
  6. git add . && git commit -m "Add basic html code"
  7. dodanie kodu HTML nagłówka strony (np. banner i nawigacja),
  8. git add . && git commit -m "Add html for page header"
  9. dodanie stylów nagłówka strony,
  10. git add . && git commit -m "Add style for page header"

I tak dalej.

Jak widzisz, cały czas powtarza się tutaj ten sam cykl: zmiana w plikach, git add ., git commit -m "Tytuł commita". Staraj się od samego początku stosować taki tryb pracy, aby nabrać dobrych przyzwyczajeń. Oszczędzi Ci to nerwów i problemów po rozpoczęciu pracy w zawodzie web developera.

Zadanie: pierwsze samodzielne commity

Twoim zadaniem będzie założenie nowego repozytorium lokalnego o nazwie learning-git-2 i wypełnienie go commitami.

Rób commit po każdej większej zmianie w plikach (dodanie nowego elementu HTML na stronie, dodanie stylów do elementu, etc.) - wykonaj przynajmniej trzy commity. Do jednego z commitów dodaj tag. Po każdej komendzie w terminalu zapisz zrzut ekranu (najlepiej samego okna terminala).

Efektem Twoich prac ma być strona z tekstem piosenki/wiersza, wykonana zgodnie z dobrymi praktykami, zarówno pod względem kodu, jak i korzystania z Gita.

Posługując się wskazówkami z poprzednich submodułów, wykonaj następujące operacje:

  1. Załóż nowe repozytorium lokalne o nazwie learning-git-2.
  2. Zainicjuj w nim Gita.
  3. Stwórz w nim podstawową strukturę katalogów oraz dodaj pliki: index.html i css/style.css (plik HTML otwórz w swojej przeglądarce i odświeżaj po każdej zapisanej zmianie w plikach, by zobaczyć efekt na ekranie).
  4. Zrób commit z tytułem "Init project".
  5. Dodaj do pliku HTML podstawową strukturę (doctype, html, head, etc.).
  6. Znajdź w internecie tekst dowolnej piosenki lub wiersza.
  7. Zbuduj prostą stronę prezentującą ten tekst. Pamiętaj o poprawnym podziale na nagłówki, akapity, etc. Dodaj podstawowe style, aby całość wyglądała estetycznie.

Przykładowy efekt:

image

Zestaw zrzutów ekranu przekaż Mentorowi w jeden z poniższych sposobów:

  • umieść je w nowym katalogu na swoim dysku sieciowym (np. Dropbox, Google Drive, etc.), wklej poniżej link do katalogu (uzyskany za pomocą guzika "Udostępnij"),
  • otwórz nowy dokument na Google Docs i przeciągnij do niego zrzuty ekranu, wklej poniżej link do tego dokumentu (uzyskany za pomocą guzika "Udostępnij"),
  • wgraj je do serwisu do współdzielenia obrazków (np. Imgur), a następnie linki do wszystkich screenów wklej do dokumentu na PasteBin, wklej poniżej link do tego dokumentu.

4.4. Git – repozytorium zdalne

Umiesz już zapisywać commity, ale nadal całe repozytorium znajduje się na Twoim dysku. Zajmiemy się teraz założeniem zdalnego repozytorium i synchronizacją pomiędzy repozytorium zdalnym i lokalnym.

Github, Gitlab, Bitbucket

Repozytorium zdalne musimy założyć na serwerze i często firmy developerskie mają własne serwery wspierające Gita. Istnieją również platformy, które udostępniają — za darmo lub odpłatnie — zdalne repozytoria Gita na swoich serwerach. Do najpopularniejszych z nich należą GitHub, GitLab oraz BitBucket.

W naszym kursie będziemy wykorzystywać GitHuba. Pozostałe serwisy działają na bardzo podobnych zasadach, więc przesiadka na któryś z nich w przyszłości, jeżeli zajdzie taka konieczność, nie powinna sprawić Ci problemu.

GitHub oferuje publiczne i prywatne repozytoria. W trakcie kursu będziemy tworzyć repozytoria publiczne, aby umożliwić Mentorowi bezproblemowe zajrzenie do plików Twoich projektów. Po kursie, tworząc np. projekty komercyjne, śmiało możesz używać repozytoriów prywatnych.

Konfiguracja: klucze SSH

Zanim przejdziemy do nauki obsługi repozytoriów zdalnych, poświęcimy chwilę na konfigurację, dzięki czemu znacznie ułatwimy sobie pracę.

Publiczne repozytorium oznacza, że jest dostępne dla każdego, ale tylko do odczytu. Aby zapisywać commity do zdalnego repozytorium, nadal będziemy musieli przechodzić autoryzację, np. za pomocą podania hasła. W praktyce będziemy się łączyć ze zdalnym repozytorium wielokrotnie w ciągu projektu (a nierzadko też w ciągu jednego dnia), więc wpisywanie hasła za każdym razem byłoby uciążliwe.

Tu z pomocą przychodzą nam klucze SSH. Są to specjalnie wygenerowane ciągi znaków, które będą zapisane w dwóch plikach:

  • id_rsa.pub — w tym pliku będzie znajdował się klucz publiczny,
  • id_rsa — w tym pliku znajdziesz swój klucz prywatny.

W wielkim skrócie, klucz publiczny można udostępniać każdemu, ponieważ służy on wyłącznie do zaszyfrowania jakiegoś tekstu. Natomiast klucz prywatny musi być zachowany w tajemnicy, ponieważ pozwala on na odszyfrowanie zaszyfrowanego tekstu.

Metafora – klucze SSH

Wyobraź sobie, że prowadzisz wypożyczalnię rowerów. Do każdego roweru dołączasz zapięcie, ale w momencie wypożyczenia jest ono rozpięte i Twój klient nie ma do niego kluczyka. To zapięcie to Twój klucz publiczny. Klient może zwrócić rower o każdej porze, przypinając go do stojaka przed Twoją wypożyczalnią. Rano używasz swojego kluczyka do odpięcia zwróconych rowerów. Ten kluczyk to Twój klucz prywatny.

Tylko Ty masz dostęp do kluczyka, więc nikt oprócz Ciebie nie będzie w stanie odpiąć rowerów — nawet klient, który przed chwilą przypiął rower do stojaka, nie może go ponownie odpiąć.

Tej technologii używa się m.in. do szyfrowania maili, ale Git, korzystając z komunikacji poprzez protokół SSH, będzie ich używał do autoryzacji, czyli zastąpi konieczność wpisywania hasła.

Zajmiemy się teraz wygenerowaniem Twoich kluczy SSH.

Sprawdzenie, czy klucze SSH już istnieją

Zanim przejdziemy dalej, upewnij się, że nie masz już wygenerowanych kluczy SSH. W przeciwnym wypadku istniejące klucze zostaną nadpisane nowymi.

Co prawda można mieć jednocześnie kilka zestawów kluczy, ale wymaga to dodatkowej konfiguracji. Zwykle wystarczy jeden zestaw kluczy dla danego konta użytkownika na komputerze.

Jeśli nie wiesz, czy posiadasz już wygenerowane klucze, możesz to sprawdzić, wpisując w terminalu komendę:

ls -al ~/.ssh

Nie masz wygenerowanych kluczy, jeśli:

  • wyświetli się błąd (np. "file does not exists"), lub
  • wyświetli się informacja o pustym katalogu, tzn. jedyne pliki, jakie zostaną wyświetlone to "." i ".." (czyli kropka i dwie kropki)

Masz wygenerowane klucze, jeśli powyższa komenda pokaże Ci jakikolwiek plik z rozszerzeniem .pub oraz drugi plik o tej samej nazwie, ale bez rozszerzenia, np. id_rsa.pub i id_rsa.

Jeśli udało Ci się znaleźć wspomniane pliki, nie musisz generować nowych kluczy. Przejdź od razu do podrozdziału "Konfiguracja kluczy SSH w GitHubie".

Generowanie kluczy SSH

Teraz w kilku krokach wyjaśnimy, jak wygenerować klucze SSH.

Krok 1

Najpierw otwórz terminal i wykonaj poniższą komendę, pamiętając, aby zamienić przykładowy adres na swój email:

ssh-keygen -t rsa -b 4096 -C "adres@example.com"

Proszę nie regulować odbiorników ;)

Na poniższych ilustracjach zostały ukryte dane prywatne, takie jak adres email, nazwa użytkownika i szczegółowe informacje dotyczące klucza prywatnego.

Pamiętaj, aby nie publikować tego rodzaju informacji również na swój temat. Nawet jeśli informacje z pojedynczego zrzutu ekranu nie stanowią luki bezpieczeństwa, może okazać się, że suma informacji z wielu zrzutów i postów opublikowanych w internecie może w przyszłości okazać się problemem.

W pierwszym pytaniu skrypt prosi nas o podanie, w jakim pliku ma zostać zapisany klucz prywatny (klucz publiczny będzie pod tą samą ścieżką, ale z rozszerzeniem .pub). Możemy śmiało wcisnąć enter, aby potwierdzić domyślną lokalizację, podaną w nawiasie.

image
Krok 2

W kolejnym kroku jesteśmy proszeni o podanie hasła do naszego klucza prywatnego. Na potrzeby tego kursu możemy śmiało wcisnąć enter, aby zatwierdzić puste hasło.

image

Po co hasło do klucza prywatnego?

Hasło do klucza prywatnego jest dodatkową warstwą zabezpieczenia. Dzięki temu, nawet gdyby ktoś zdobył Twój klucz prywatny (np. poprzez kradzież komputera), nie będzie mógł używać Twojego klucza prywatnego do zalogowania się na serwerze (np. korzystania z GitHuba bez hasła) czy odszyfrowania Twoich danych zaszyfrowanych tym kluczem.

W przypadku użycia hasła do klucza będzie trzeba raz wprowadzić hasło. Będzie ono zapamiętane aż do czasu wyłączenia lub restartu komputera. Są różne metody zapamiętywania hasła do klucza w ten sposób, np. komenda ssh-add, o której znajdziesz więcej informacji np. pod tym linkiem.

Gorąco zachęcamy do stworzenia klucza z hasłem, ale biorąc pod uwagę przystępność dla osób z mniejszym doświadczeniem w obsłudze terminala, zakładamy, że klucz zostanie stworzony bez hasła.

Krok 3

Następny krok to potwierdzenie hasła — jeśli w poprzednim kroku nie było podane żadne hasło, tutaj też niczego nie wpisujemy i wciskamy enter.

image

Był to ostatni krok, po którym wyświetlane są informacje dotyczące stworzonych kluczy. Zwróć szczególną uwagę na linię zaczynającą się od "Your public key has been saved in" - w tej linii podana jest lokalizacja pliku z Twoim kluczem publicznym.

image

Konfiguracja kluczy SSH w GitHubie

Przejdź teraz na stronę GitHuba. Jeśli masz już konto w tym serwisie, zaloguj się. W przeciwnym razie załóż konto teraz, podając nazwę użytkownika (będzie się wyświetlać przy Twoich projektach), adres email oraz hasło.

Po zalogowaniu zobaczysz swój panel GitHub. Kliknij ikonę użytkownika po prawej stronie, a następnie wybierz Ustawienia:

image

Nie przejmuj się, jeśli Twoja strona wygląda inaczej niż powyższa ilustracja - dla nowych kont wyświetlana jest inna zawartość.

Na stronie ustawień kliknij w lewej kolumnie "Klucze SSH i GPG", a potem po prawej stronie, w sekcji "Klucze SSH" kliknij guzik "Dodaj nowy klucz":

image

Zobaczysz formularz dodawania nowego klucza, z polami na Tytuł i Klucz. W polu Tytuł możesz wpisać co chcesz — to pole służy tylko do rozróżnienia kluczy (do jednego konta można dodać wiele kluczy, np. jeśli używasz tego konta na różnych komputerach). Możesz np. wpisać "Mój klucz".

W pole Klucz musisz wkleić zawartość swojego pliku id_rsa.pub. W tym celu w swoim terminalu wpisz komendę cat ~/.ssh/id_rsa.pub:

image

Zwróć uwagę, że mówimy tutaj o kluczu publicznym, czyli z rozszerzeniem .pub – tylko ten klucz możesz gdziekolwiek podać. Rozpoznasz go po tym, że jego treść zaczyna się od tekstu ssh-rsa, a kończy się Twoim adresem email.

Przypomnienie

Pamiętaj, że zarówno klucz publiczny (id_rsa.pub), jak i prywatny (id_rsa) muszą pozostać w katalogu .ssh. Jeśli którykolwiek z nich usuniesz lub przeniesiesz w inne miejsce na dysku, klucze nie będą działać.

Po wyświetleniu klucza w terminalu zaznacz go za pomocą myszki, a następnie skopiuj (ctrl+shift+c). Wklej go w ustawieniach GitHuba w polu Klucz, a następnie zatwierdź guzikiem "Dodaj klucz SSH":

image

I to wszystko — klucz SSH jest już skonfigurowany i może być wykorzystywany do pracy. Teraz możemy przejść do założenia pierwszego repozytorium na GitHubie

Zakładanie repozytorium na GitHubie

Każdy projekt powinien mieć własne repozytorium. Całe szczęście, ta operacja jest bardzo prosta.

Konfiguracja w panelu GitHuba

Przejdź na stronę główną GitHuba, aby zobaczyć swój panel użytkownika. Kliknij guzik "Rozpocznij projekt", aby założyć nowe repozytorium:

image

Po kliknięciu guzika pojawi się formularz. Jedynym polem, które musisz wypełnić, jest nazwa tworzonego repozytorium. Nie wypełniaj i nie zaznaczaj pozostałych pól.

image

Dlaczego nie zaznaczamy pozostałych pól

Aby bezproblemowo zacząć pracę, co najmniej jedno z repozytoriów (lokalnego i zdalnego) musi być puste. Gdybyśmy zaznaczyli którąś z opcji dot. README, .gitignore lub licencji, zostałby automatycznie stworzony pierwszy commit, a więc repozytorium zdalne nie byłoby puste.

W naszym przypadku, kiedy mamy już zmiany w repozytorium lokalnym, nie chcemy, aby w zdalnym pojawił się jakikolwiek automatyczny commit, więc nie zaznaczamy tych opcji.

Po zatwierdzeniu guzikiem "Utwórz repozytorium" wyświetlą się informacje dotyczące sposobów korzystania z repozytorium:

image

Nie przejmuj się, jeśli nie rozumiesz, o co w tym chodzi — za chwilę wszystkiego się nauczysz. :)

Pod sekcją "Quick setup" znajdują się trzy scenariusze wykorzystania pustego repozytorium. Pierwszy z nich zakłada, że dopiero zaczynasz projekt i nie masz jeszcze lokalnego repozytorium. W rozdziale "Alternatywa do podłączania — klonowanie repozytorium" zajmiemy się tym scenariuszem, ale zamiast komend przedstawionych przez GitHub zaproponujemy Ci inne rozwiązanie.

Drugi scenariusz to podłączenie repozytorium zdalnego do lokalnego, które już istnieje — tym scenariuszem zajmiemy się już za moment.

Trzecia opcja pozwala na zaimportowanie innego zdalnego repozytorium. Jako że jest to rzadziej wykorzystywana opcja, nie będziemy się nią zajmować.

Na razie najważniejsze jest dla nas, aby w pierwszej sekcji ("Quick setup") była zaznaczona opcja SSH. Właśnie po to generowaliśmy i konfigurowaliśmy klucze SSH.

Czego unikać

Najczęstszym problemem nowych użytkowników GitHuba jest sytuacja, w której mają dwa repozytoria — lokalne i zdalne — i w każdym z nich mają już zapisane jakieś commity. Połączenie tych dwóch repozytoriów jest bardzo problematyczne.

Dlatego trzymaj się zasady, że co najmniej jedno z nich powinno być puste (tzn. świeżo założone).

Przejdźmy teraz do drugiego z wymienionych powyżej scenariuszy — mamy już lokalne repozytorium w projekcie i chcemy do niego podłączyć repozytorium zdalne.

Podłączanie repozytorium zdalnego do lokalnego

Otwórz terminal i wejdź do katalogu z zadaniem z poprzedniego submodułu. Sprawdź za pomocą git tree, jak obecnie wygląda historia zmian.

image

Skopiuj teraz komendę zaczynającą się od git remote add ze strony repozytorium na Githubie:

image

Pamiętaj, że nie możesz przepisać komendy z powyższej ilustracji — w adresie znajduje się nazwa użytkownika ("kodilla-kursy") oraz nazwa repozytorium ("nauka-gita").

Wklej skopiowaną komendę do swojego terminala (ctrl+shift+v) i zatwierdź klawiszem enter. Następnie sprawdź listę dodanych serwerów za pomocą komendy git remote -v.

image

Co się tutaj zadziało? Komenda git remote add dodaje do repozytorium lokalnego adres, pod jakim znajduje się repozytorium zdalne. Słowo origin jest nadawaną przez nas nazwą dla tego adresu — nadajemy nazwę dlatego, że jedno repozytorium lokalne może być synchronizowane z wieloma repozytoriami zdalnymi. Przyjęło się, że podstawowe repozytorium zdalne nazywa się właśnie origin, ale równie dobrze możesz podać inną nazwę.

Przykład zastosowania

Wyobraź sobie, że jesteś częścią zespołu pracującego nad projektem. Wasz klient sam jest programistą i chce mieć dostęp do repozytorium projektu. Z zespołem ustaliliście jednak, że chcielibyście udostępniać klientowi zmiany dopiero po przetestowaniu, czy wszystko działa poprawnie.

W takiej sytuacji możecie założyć jedno repozytorium zdalne, do którego dostęp ma tylko Wasz zespół (nazwijmy je origin), i drugie z dostępem dla klienta ("client").

Na co dzień, przy bieżącej pracy, synchronizujecie swoje lokalne repozytoria ze zdalnym origin. Raz w tygodniu testujecie cały projekt, naprawiacie ewentualne błędy, i dopiero wtedy synchronizujecie repozytorium lokalne z "client".

Klient będzie widział wszystkie commity, które były dodane w trakcie prac, ale dzięki temu będziecie mieć pewność, że najnowszy commit w repozytorium "client" będzie zawsze poprawnie działającym projektem.

Komenda git remote -v wyświetliła nam dwa razy ten sam adres, ponieważ Git zapisuje sobie osobno adres do pobierania zmian z serwera (ang. "fetch") oraz wysyłania zmian na serwer (ang. "push").

Nasze repozytorium lokalne już zna adres repozytorium zdalnego, ale jeszcze nie zostały wysłane żadne dane. Zrób to za pomocą komendy git push -u origin master. Słowo master już pojawiło się w tym module – master to po prostu nasz główny branch.

Pierwsze połączenie z serwerem

Kiedy pierwszy raz łączysz się z serwerem za pomocą protokołu SSH, wyświetli się prośba o potwierdzenie.

image

Po wpisaniu słowa "yes" i zatwierdzeniu enterem, to pytanie nie powinno się pojawić ponownie na tym samym komputerze, jeżeli łączysz się z tym samym serwerem (np. GitHubem).

Jest to dodatkowe zabezpieczenie przed sytuacją, w której ktoś podszyłby się pod serwer, z którym próbujesz się połączyć. W związku z tym jest to normalne przy pierwszym połączenia i powinno zwrócić Twoją uwagę tylko, gdyby pojawiło się przy kolejnym połączeniu.

Po wykonaniu komendy wyświetlą się dodatkowe informacje dotyczące przesłanych informacji. Może to zająć krótką chwilę, ale powinien pojawić się z powrotem znak zachęty:

image

Wszystkie dotychczasowe zmiany z naszego repozytorium zostały wysłane na serwer. Możesz to sprawdzić, odświeżając stronę repozytorium.

image

Interfejs GitHuba omówimy sobie w kolejnym submodule, ale jeśli masz ochotę, możesz pozwiedzać tę stronę. W szczególności warto zwrócić uwagę na link "Commits" (na ilustracji jest to pierwszy link nad czerwonym paskiem).

Alternatywa do podłączania — klonowanie repozytorium

W naszej sytuacji mieliśmy już lokalne repozytorium z zapisanymi commitami. W pracy spotkasz się jednak częściej z sytuacją, kiedy będziesz dołączać do toczącego się projektu. W takiej sytuacji będzie już istniało repozytorium zdalne z zapisanymi commitami i pojawi się potrzeba sklonowania tego repozytorium.

Będzie Ci też wygodniej przy nowych zadaniach w ramach Bootcampa zakładać od razu repozytorium zdalne i z niego klonować swoje repozytorium lokalne.

Pamiętaj, że stosujemy klonowanie tylko w sytuacji, kiedy istnieje repozytorium zdalne, a nie istnieje lokalne na Twoim komputerze.

Stworzymy teraz nowe repozytorium, które będzie "udawać" repo projektu, do którego dołączasz. Możesz do tego wykorzystać ikonę plusa, która znajduje się w prawym górnym rogu strony:

image

Tym razem przy zakładaniu repozytorium zaznacz opcję stworzenia pliku README.md, co sprawi, że automatycznie zostanie zapisany pierwszy commit. Dzięki temu zobaczysz, jak działa klonowanie w sytuacji, kiedy w zdalnym repozytorium istnieją już jakieś zmiany.

image

Po stworzeniu repozytorium skopiuj adres repozytorium zdalnego. W przypadku pustego repozytorium wyświetlał się w podpowiedziach widocznych od razu po stworzeniu repozytorium. Tym razem jednak repozytorium nie jest puste, więc adres znajdziesz po prawej stronie nad listą plików, pod guzikiem "Sklonuj lub pobierz":

image

Następnie otwórz swój terminal i przejdź do katalogu z projektami. Wykonaj komendę git clone adres-repozytorium, oczywiście zamieniając "adres-repozytorium" na adres skopiowany przed chwilą. Po sklonowaniu repozytorium zostanie utworzony katalog o nazwie takiej samej jak nazwa repozytorium. Wejdź do tego katalogu i wyświetl historię zmian oraz listę plików.

image

Jak widzisz, za pomocą jednej komendy git clone zostały wykonane operacje stworzenia katalog projektu, zainicjowania repozytorium, dodania adresu zdalnego repozytorium i pobrania zmiany z serwera. Masz teraz na swoim komputerze dokładną kopię zdalnego repozytorium.

Co zrobić w przypadku błędu

Przeczytać komunikat w terminalu. To zdecydowanie najlepszy pierwszy krok.

image

Częstym błędem na tym etapie jest sytuacja, w której w Twoim katalogu z projektami istnieje już niepusty katalog o takiej samej nazwie jak repozytorium, które klonujesz. W takiej sytuacji należy na końcu komendy dodać (po spacji) nazwę katalogu, do którego ma być skopiowane repozytorium.

Podłączanie repo — podsumowanie

Krótkie przypomnienie metod podłączania zdalnego repozytorium:

Zaczynam nowy projekt, nie mam żadnego repozytorium ani plików:

  1. Zakładam repozytorium na GitHubie, przy zakładaniu mogę zaznaczyć inne opcje poza tytułem repozytorium.
  2. Klonuję repozytorium na swój dysk za pomocą komendy git clone adres-repozytorium.

Mam repozytorium lokalne:

  1. Zakładam puste repozytorium na GitHubie — przy zakładaniu wypełniam tylko nazwę repozytorium.
  2. Podłączam adres repozytorium zdalnego do lokalnego za pomocą komendygit remote add origin adres-repozytorium.
  3. Wykonuję pierwsze wysłanie commitów do zdalnego repozytorium za pomocą komendy git push -u origin master.

Nie mam repozytorium lokalnego, ale mam pliki projektu na dysku:

  1. Mogę zastosować pierwszy sposób, a następnie do katalogu sklonowanego repozytorium przenieść pliki projektu, lub
  2. mogę zainicjować repozytorium w katalogu tego projektu za pomocą komendy git init, wykonać pierwszy commit, i dalej postępować wedle drugiego sposobu (czyli "Mam repozytorium lokalne").

Podstawowe komendy Gita

Push, czyli wysyłamy nasze zmiany na zdalne repo

Do wysłania commitów z repozytorium lokalnego do zdalnego służy komenda git push.

Jeśli podłączamy adres repozytorium zdalnego do lokalnego za pomocą komendy git remote add adres-repozytorium, to przy pierwszym użyciu komendy git push musimy dodać flagę -u oraz słowa origin master – komendę w tej formie podaliśmy Ci w poprzednim rozdziale. Pamiętaj jednak, że dotyczy to tylko tej konkretnej sytuacji. W pozostałych przypadkach będziemy używać komendy git push bez żadnych argumentów.

Pull, czyli pobieramy zmiany ze zdalnego repo

Ogólnie rzecz ujmując, komenda git pull jest odwrotnością git push, czyli pobiera zmiany z repozytorium zdalnego do lokalnego. Normalnie ma zastosowanie, kiedy ktoś inny pracuje w tym samym projekcie, ale zasymulujemy tę sytuację, korzystając z interfejsu GitHuba.

Uwaga

Przed rozpoczęciem ćwiczenia, które opisujemy poniżej, wykonaj następujące kroki:

  1. Wykonaj git status – jeśli wyświetlą się jakieś zmiany do zapisania, wykonaj git add . && git commit -m "Tytuł commita".
  2. Wykonaj git push.

W przeciwnym wypadku mógłby pojawić się tzw. "konflikt", czyli Git mógłby nie poradzić sobie z pogodzeniem zmian z repozytoriów zdalnego i lokalnego.

Jeśli cokolwiek pójdzie nie tak, nie przejmuj się — możesz ponownie sklonować zdalne repozytorium do katalogu o innej nazwie i kontynuować naukę w tym nowym katalogu.

Wejdź na stronę repozytorium, na którym pracowaliśmy w poprzednim rozdziale. Na tej stronie widoczna jest lista plików.

image

Kliknij którąś z nazw plików, np. index.html, a następnie w ikonę ołówka.

image

Znajdujesz się teraz w trybie edycji tego pliku — zmień jego treść w dowolny sposób. Następnie na dole strony wypełnij tytuł commita i potwierdź zapisanie guzikiem.

image

Ponownie zobaczysz podgląd pliku, tym razem już z wprowadzonymi zmianami. Przejdź teraz do swojego terminala i wykonaj komendę git pull, a następnie wyświetl historię zmian.

image

Jak widzisz, na szczycie listy pojawił się najnowszy commit, wykonany przez interfejs GitHuba. Dzięki temu mogliśmy zaktualizować nasze repozytorium lokalne o commit, który pojawił się na repozytorium zdalnym.

Przetestuj to jeszcze raz samodzielnie, ale tym razem zrób dwa commity za pomocą interfejsu GitHuba, a dopiero potem wykonaj git pull.

Zadanie: pierwsze repozytorium na GitHubie

Potrafisz już założyć repozytorium zdalne i połączyć je z lokalnym. Umiesz też sklonować repo zdalne na swój komputer.

W tym zadaniu połączysz swoje repozytorium lokalne (to, w którym masz projekt z piosenką/wierszem, czyli learning-git-2) z GitHubem. Podążaj za instrukcjami w sekcji "Podłączanie repo — podsumowanie" i wrzuć pierwszy commit na GitHuba (będzie w nim cały Twój dotychczasowy projekt). Wykonaj jeszcze dwa commity z dowolnymi zmianami i również wyślij je na GitHuba.

Następnie wklej link do swojego repozytorium poniżej i wyślij do Mentora.

4.5. NPM - rozpoczęcie pracy w projekcie

Nasze środowisko developerskie się rozrasta! Mamy już katalog roboczy, edytor kodu oraz repozytorium. Ciągle jednak sporo czynności w projekcie musimy wykonywać "na piechotę". Czas usprawnić sobie pracę i wejść na kolejny poziom developerskiego wtajemniczenia – oto manager pakietów! Za jego pomocą zbudujemy task runner, który zautomatyzuje nam niektóre działania.

Czym jest manager pakietów?

Zapewne zdajesz sobie sprawę, że każda firma zajmująca się web developmentem realizuje projekty nieco inaczej. Przykładem może być stosowanie preprocesorów CSS (np. Sass) lub innych modułów wspomagających prace nad projektem. Tylko skąd brać te moduły?

Odpowiedzią na tę sytuację jest manager pakietów. Pozwala on na szybkie dodanie do naszego projektu potrzebnych narzędzi. Co więcej, może się okazać, że narzędzie z którego chcesz korzystać wymaga zainstalowania kilku innych pakietów. Manager pakietów sam zajmie się instalowaniem dodatkowych zależności, więc nie będziemy musieli się tym zajmować.

Jeśli nie do końca rozumiesz czym jest manager pakietów, możesz wyobrazić go sobie jako świetnego sprzedawcę w sklepie z narzędziami. Kiedy powiesz mu, że potrzebujesz wiertarki, sam doda Ci odpowiednie wiertła i przedłużacz. A jeśli Twój kolega będzie chciał kupić taki sam zestaw, wystarczy że skserujesz dla niego swój paragon i dostanie dokładnie taki sam zestaw.

Dzięki managerowi pakietów prostsza staje się też praca zespołowa nad projektem. Wystarczy, że każdy będzie miał ten sam plik konfiguracyjny (np. umieszczony przy pomocy Gita na serwerze) i będzie mógł za pomocą jednej komendy zainstalować wszystkie narzędzia potrzebne do pracy nad danym projektem.

W naszym przypadku managerem pakietów będzie NPM, czyli NodeJS Package Manager. Dzięki niemu będziemy mogli szybko rozpoczynać nowe projekty, kopiując do nich konfigurację z poprzedniego projektu.

NPM pozwala na zainstalowanie olbrzymiej liczby pakietów. Jako przykłady można wymienić narzędzia służące do:

  • sprawdzania poprawność kodu,
  • łączenia oraz minifikacji plików, która oznacza m.in. usunięcie spacji, tabów i nowych linii, dzięki czemu zmniejszy się rozmiar plików pobieranych przez każdego odwiedzającego naszą stronę,
  • wstawiania fragmentów kodu, np. tej samej stopki na wszystkich podstronach,
  • dodawania w css właściwości z prefiksami przeglądarek, jeśli są wymagane,
  • kasowania niepotrzebnych plików, np. "osieroconego" pliku .css wygenerowanego kiedyś z pliku .scss, który został już usunięty,
  • tworzenia paczki .zip całego projektu,
  • automatycznego odświeżania strony po zapisaniu zmian w plikach, co jest szczególnie przydatne przy pracy na dwóch ekranach.

Pod koniec tego modułu zainstalujesz za pomocą NPM-a kilka podstawowych pakietów, które pozwolą Ci usprawnić pracę.

Czym jest task runner?

Task runner służy do uruchamiania wielu narzędzi za pomocą jednej komendy. Co więcej, takich komend może być kilka i każda z nich będzie służyła do innego celu. Na przykład inny zestaw narzędzi będzie potrzebny do bieżącej pracy nad projektem niż do wygenerowania plików gotowych do publikacji na serwerze.

image

Możesz wyobrazić to sobie, jako guzik "Wyjeżdżam na wakacje" u siebie w domu — po wciśnięciu zostałyby wyłączone światła, zasunięte rolety i zakręcone zawory wody i gazu, oraz włączony alarm. Wszystkie te czynności mógłbyś wykonać sam, ale wygodniej by było mieć jeden guzik — zwłaszcza jeśli miałbyś go często używać.

Task runner pozwoli na przyspieszenie i automatyzację czynności, które musimy często wykonywać. Nie będzie potrzeby pamiętania które narzędzia trzeba uruchomić w danym projekcie — zwykle będzie to się ograniczać do jednej z kilku komend, które będą takie same w większości projektów.

Istnieje wiele task runnerów, ale w tym module wykorzystamy skrypty NPM-a do stworzenia własnego, prostego task runnera. Wybraliśmy takie rozwiązanie, ponieważ jest najprostsze w konfiguracji i pozwoli Ci samodzielnie rozbudować zestaw narzędzi wykorzystywanych do pracy nad projektami.

Alternatywne oprogramowanie

Narzędzia, których będziemy używać w naszym kursie, nie są oczywiście jedynymi, jakich można użyć. W Twojej przyszłej pracy na pewno został już wybrany zestaw technologii (tzw. stack technologiczny) wykorzystywany w danym projekcie lub jako standard w danej firmie. Dla przykładu, do kontroli wersji można użyć też SVN-a lub Mercurial zamiast Gita, a jako task runnera Grunta, Gulpa czy Webpacka. Wybór narzędzi jest kwestią preferencji programisty lub wymagań projektu.

image

Instalacja Node.js

NPM jest częścią Node.js. Musimy więc zacząć od instalacji Node.js.

Przed rozpoczęciem instalacji sprawdź, czy masz obecnie zainstalowany Node.js. W tym celu w terminalu wykonaj komendy node -v. Jeśli pojawi się numer wersji (i jest to wersja 10.x), możesz w poniższej instrukcji pominąć instalację i przejść do aktualizacji NPM.

Instalator zalecanej przez nas wersji 10.x znajdziesz pod tym adresem. Pobierz plik node-v10.16.0-x86.msi, jeśli pracujesz na 32-bitowej wersji Windowsa, lub plik node-v10.16.0-x64.msi dla wersji 64-bitowej.

Po pobraniu instalatora uruchom go i przejdź procedurę instalacji, pozostawiając wszystkie domyślne opcje.

Następnie zaktualizuj npm za pomocą terminala, wykonując komendę npm install npm@latest -g. Jej wykonanie może zająć chwilę, ale w końcu pojawi się ponownie znak zachęty.

Instalator zalecanej przez nas wersji 10.x znajdziesz pod tym adresem. Pobierz plik node-v10.16.0.pkg.

Po pobraniu instalatora uruchom go i przejdź procedurę instalacji, pozostawiając wszystkie domyślne opcje.

Następnie zaktualizuj npm za pomocą terminala, wykonując komendę npm install npm@latest -g. Jej wykonanie może zająć chwilę, ale w końcu pojawi się ponownie znak zachęty.

Zalecamy instalację Node.js w wersji 10.x za pomocą instrukcji dostępnej pod tym adresem.

Dla dystrybucji nieobjętych powyższą instrukcją znajdź w Google instrukcję instalacji, wpisując nazwę dystrybucji i hasło "install node.js 10", np. "mint linux install node.js 10".

Po zakończeniu instalacji warto wykonać aktualizację pakietu npm za pomocą komendy npm install npm@latest -g lub sudo npm install npm@latest -g, w zależności od praw użytkownika uruchamiającego komendę.

Inicjalizacja NPM-a w projekcie

Podobnie jak w przypadku Gita, w każdym projekcie należy jednorazowo zainicjować NPM-a. Otwórz terminal w projekcie nauka-gita-2 i wykonaj komendę npm init -y. Ta komenda utworzy dla nas domyślny plik konfiguracyjny package.json w głównym katalogu projektu. Jego treść została wyświetlona w komunikacie komendy.

image

Plik ten konfiguruje zachowanie NPM-a w projekcie. W nim będą znajdować się m.in. informacje o pakietach do zainstalowania.

Na potrzeby naszych zadań plik ten może pozostać w domyślnej postaci — nie musimy zmieniać domyślnych wartości, takich jak nazwa projektu czy numer wersji.

Dodajemy plik .gitignore

Nie zawsze wszystkie pliki projektu mają trafiać do repozytorium. Niezależnie od tego, czy Twój projekt już ma założone repozytorium, czy jeszcze nie, warto od razu dodać plik .gitignore, aby nie dodawać do repozytorium niepotrzebnych plików. Najlepiej do tego celu zastosować gotowy szablon przygotowany przez zespół GitHuba — możesz go znaleźć pod tym linkiem. Wystarczy, że w głównym katalogu swojego projektu utworzysz plik .gitignore za pomocą komendy touch .gitignore, otworzysz go w edytorze, przekleisz do niego zawartość szablonu z powyższego linka i zapiszesz.

Najlepiej dodawać plik .gitignore do każdego projektu, w którym korzystamy z NPM-a. Dzięki temu, jeśli w przyszłości projekt będzie miał założone repozytorium, unikniesz problemu z dodaniem do repozytorium tysięcy plików, które nie są w nim potrzebne.

Instalujemy pierwszy pakiet — BrowserSync

Przetestujemy teraz działanie NPM-a, dodając do naszego projektu pierwszy pakiet BrowserSync. Czy pamiętasz, że pracując lokalnie na plikach HTML/CSS bądź też używając edytora Kodilli, po każdej modyfikacji kodu trzeba było odświeżać podgląd, aby zobaczyć zmiany? BrowserSync znacznie ułatwia nam pracę, "obserwując" zmiany w plikach i automatycznie odświeżając podgląd.

Aby zainstalować ten pakiet, otwórz terminal w katalogu projektu nauka-gita-2 i wywołaj komendę npm install --save-dev browser-sync.

image

Ostrzeżenia przy instalacji pakietów

NPM działa na podstawie zależności. Oznacza to, że jeden pakiet może wymagać instalacji wielu innych, które również mogą mieć swoje zależności. Przy instalacji nas to nie interesuje, ponieważ NPM sam sobie z tym poradzi. Oznacza to jednak, że jeśli jedna z zależności powoduje wystąpienie jakiegoś ostrzeżenia, zostanie ono wyświetlony w trakcie instalacji.

W skrócie — na razie nie musisz się tym przejmować, jeśli są to ostrzeżenia (warn, warning), a nie błędy (err, error).

Na powyższej ilustracji widzisz kilka ostrzeżeń i pewnie zastanawia Cię, co one oznaczają. Pokrótce wyjaśniamy:

  • deprecated oznacza, że coś jest przestarzałe — innymi słowy, na ten moment działa, ale może niedługo przestać działać (przy czym "niedługo" częściej oznacza lata niż dni),
  • dwa ostrzeżenia zaczynające się od "zadanie-1-4" dotyczą pliku package.json — NPM przypomina, aby uzupełnić w nim opis projektu oraz link do repozytorium, ponieważ zakłada, że będziemy publikować nasz projekt (w naszym przypadku nie musimy tego uzupełniać),
  • SKIPPING OPTIONAL DEPENDENCY oznacza, że została pominięta opcjonalna zależność jednego z instalowanych pakietów (również nie musimy się tym przejmować).
image

Jak widzisz na powyższej ilustracji, BrowserSync został zainstalowany oraz dodany do pliku konfiguracyjnego package.json w sekcji dependencies. To właśnie dzięki temu wpisowi inny developer w tym samym projekcie będzie mógł szybko zainstalować BrowserSynca, a docelowo — wszystkie pakiety NPM potrzebne do pracy nad projektem.

Informacja dla zaawansowanych

Flaga --save powinna być używana dla pakietów wymaganych do działania projektu w celu jego uruchomienia i poprawnego działania. Dla odmiany, pakiety potrzebne do pracy nad projektem oraz jego testowania powinny być instalowane z flagą --save-dev, która w pliku package.json dokona wpisu w sekcji devDependencies.

W naszym przypadku wszystkie narzędzia, których będziemy używać w tym module, są wymagane tylko do pracy nad projektem, czyli zawsze używamy flagi --save-dev.

BrowserSync — pierwsze uruchomienie

Aby uruchomić BrowserSynca, w terminalu w projekcie, w którym jest on zainstalowany, wykonaj komendę:

node_modules/.bin/browser-sync start --server --files "css/*.css" "*.html"

W rezultacie powinna automatycznie otworzyć się strona w domyślnej przeglądarce. Adres strony może różnić się numerem portu (czyli liczbą po dwukropku w adresie URL), ale domyślnie jest to http://localhost:3000/. Jednocześnie w terminalu możesz zobaczyć taki komunikat:

image

Zauważ, że nie pojawił się ponownie znak zachęty. Oznacza to, że BrowserSync będzie działał tak długo, aż zatrzymamy go za pomocą kombinacji klawiszy Ctrl+C. Pamiętaj, że jeśli w czasie jego działania zechcesz uruchomić inną komendę, musisz otworzyć kolejne okno terminala.

Dzięki temu, że BrowserSync już pracuje, możesz teraz wprowadzić i zapisać jakąkolwiek zmianę w pliku .html lub .css — przeglądarka automatycznie odświeży stronę i pokaże Twoje zmiany.

W zależności od konfiguracji Twojego komputera oraz routera inne urządzenia (np. smartfon) podłączone do tej samej sieci (np. do tego samego wifi) mogą również widzieć ten sam podgląd strony, korzystając z adresu podanego w komunikacie wyświetlonym w terminalu przy etykiecie "External". Pozwala to na testowanie strony na wielu urządzeniach jednocześnie, co pozwala na oszczędność czasu.

Po zakończeniu pracy możesz wyłączyć działanie BrowserSync, przechodząc do okna terminala, w którym jest uruchomiony, i wciskając kombinację klawiszy Ctrl+C.

Oto Twój pierwszy zainstalowany i uruchomiony pakiet! Za chwilę dodamy ich jeszcze kilka, ale nie martw się — nie będzie konieczne uruchamianie każdego z nich równie długą komendą. Z pomocą przyjdzie nam wspomniany już task runner, dzięki któremu włączymy wiele pakietów za pomocą jednego krótkiego polecenia.

Zadanie: instalacja i uruchamianie pakietów

Zanim przejdziemy do budowania task runnera, wykonaj krótkie ćwiczenie, aby oswoić się z komendami różnych pakietów i ich dokumentacją. Przyda Ci się to już w kolejnym module, aby lepiej zrozumieć, co dzieje się w naszym task runnerze.

W tym zadaniu cały czas pracujemy na repozytorium z poprzednich ćwiczeń (tym, gdzie masz projekt z piosenką/wierszem). Upewnij się, że masz w nim zainicjalizowanego Gita (poznasz to po obecności katalogu .git), dodany plik .gitignore, zainicjalizowanego NPM-a (czyli czy w katalogu projektu jest plik package.json) i zainstalowany pakiet BrowserSync (powinien być obecny w pliku package.json, w sekcji devDependencies). Jeżeli brakuje któregoś z tych elementów, cofnij się do poprzednich submodułów i dodaj je.

Następnie, już samodzielnie, zainstaluj w tym projekcie następujące pakiety z flagą --save-dev:

  • autoprefixer-cli - konwertuje plik CSS, dodając prefiksy wymagane przez niektóre przeglądarki np. dla właściwości display: flex,
  • html-validate - sprawdza poprawność kodu HTML.

Komendy instalacji tych pakietów znajdziesz w ich dokumentacji (kliknij ich nazwy na liście powyżej). Pamiętaj, że dokumentacja to cenne źródło wiedzy — przyzwyczajaj się do korzystania z niej jak najczęściej!

Na końcu dodaj w projekcie plik komendy.txt i umieść w nim przykłady komend uruchamiających powyższe dwa narzędzia, gdzie:

  • autoprefixer-cli ma czytać z pliku style.css i zapisywać wynik do pliku style.prefixed.css (możesz przetestować działanie Autoprefixera np. wpisując w pliku style.css regułę z display: flex),
  • html-validate ma wyświetlać listę błędów we wszystkich plikach .html.

Jeżeli nie masz pewności, jak to zrobić, odwołaj się do dokumentacji.

Po wykonaniu zadania zaktualizuj repozytorium zdalne, wklej poniżej link do niego i wyślij do Mentora.

4.6. NPM - budujemy własny task runner

W poprzednim module zainstalowaliśmy nowe narzędzia pomagające w pracy nad projektem i umiesz już się nimi posługiwać. Nie ma jednak potrzeby, żeby tracić czas na uruchamianie każdego z nich z osobna. Dlatego właśnie zajmiemy się teraz automatyzacją uruchamiania naszych narzędzi - zbudujemy prosty task runner oparty o skrypty NPM. Skrypty te to nic innego, jak aliasy wykonujące zdefiniowane komendy.

Zwykle w task runnerze definiuje się kilka różnych scenariuszy, nazywanych taskami. Najczęściej spotykanymi taskami są:

  • build, który konwertuje pliki źródłowe (te, w których piszemy kod), na pliki gotowe do opublikowania na serwerze - np. może to być skonwertowanie plików .scss na .css, użycie Autoprefixera, minifikacja plików .js i/lub .css (zmniejszenie ich rozmiaru m.in. poprzez usunięcie spacji i enterów), etc.,
  • watch, który działa w trakcie pracy nad projektem i na bieżąco wykonuje potrzebne operacje na plikach, np. konwertuje pliki .scss na .css po każdym zapisaniu pliku .scss,
  • test, który sprawdza poprawność kodu, np. przeprowadzając walidację składni plików .html, .css i/lub .js.

Dzięki standaryzacji tych nazw tasków w każdym projekcie uruchamia się je w ten sam sposób, nawet jeśli uruchamiają one różne narzędzia.

Każdy task może uruchamiać również inne taski, więc np. build może uruchamiać task test, aby każde wygenerowanie wersji "produkcyjnej" wiązało się ze sprawdzeniem poprawności kodu.

Ponadto, często stosuje się mniejsze taski, dla zachowania przejrzystości. I tak np. walidacja plików .html może odbywać się w tasku o nazwie test:html, który będzie uruchamiany przez task test. W tym wypadku dwukropek jest po prostu częścią nazwy, która wygodnie rozdziela nam "kategorię" taska od jego konkretnego przeznaczenia.

Struktura task runnera

W tym submodule napiszemy te trzy taski plus jeden dodatkowy, który przyspieszy nam rozpoczęcie pracy z nowymi projektami. Będą one wykonywały za nas następujące operacje:

  • init-project

    • instalacja niezbędnych pakietów
    • stworzenie struktury katalogów, czyli założenie folderów sass/, css/, vendor/, images/, js/
    • stworzenie pliku README.md, który powinien się znajdować w każdym repozytorium
    • stworzenie pustych plików index.html, sass/style.scss, js/script.js
    • pobranie pliku .gitignore i umieszczenie go w katalogu naszego projektu
  • test

    • sprawdzanie poprawności HTML
  • build

    • konwersja plików .scss do .css
    • uruchomienie Autoprefixera
    • minifikacja pliku .css (usunięcie pustych linii w celu zmniejszenia rozmiaru pliku)
    • przetestowanie poprawności kodu
  • watch

    • kompilowanie na bieżąco plików .scss do .css
    • dodawanie prefiksów w plikach .css
    • odświeżanie przeglądarki po każdej zmianie w kodzie

Uff! Sporo tego. Na szczęście do wszystkich tych zadań istnieją odpowiednie pakiety NPM, które wystarczy tylko zainstalować i uruchomić w odpowiedni sposób. Dla zwiększenia czytelności naszego task runnera, każde zadanie w tasku będzie osobną komendą. Później task tylko wywoła te komendy w odpowiedniej kolejności. Zaczynamy!

Na początku załóż nowy folder w swoim katalogu roboczym i nazwij go task-runner. Zainicjuj w tym folderze Gita i NPM za pomocą znanych Ci już komend: git init oraz npm init -y. Otwórz w edytorze plik package.json, który utworzył nam NPM.

W tym pliku będziemy pisać skrypty naszego task runnera. Na razie plik wygląda tak:

image

Interesować nas będzie przede wszystkim linia 6, czyli scripts. Jak widzisz, NPM domyślnie tworzy nam jeden z tasków, czyli test. Na razie nie robi on nic specjalnego i jeszcze przez chwilę nie będziemy się nim przejmować. Zaczniemy po kolei – aby mieć co testować, należy przede wszystkim stworzyć projekt! Zajmiemy się więc najpierw taskiem init-project.

Task 1: inicjalizacja projektu

Zgodnie ze schematem rozpisanym powyżej, podzielimy sobie ten task na kilka subtasków:

  • instalacja niezbędnych pakietów,
  • stworzenie struktury katalogów,
  • stworzenie pliku README.md,
  • stworzenie pustych plików index.html, sass/style.scss, js/script.js,
  • pobranie pliku .gitignore.

Instalacja niezbędnych pakietów

Kiedy dołączasz do istniejącego projektu, w którym jest już zainicjowany NPM (czyli takiego, gdzie istnieje już plik package.json), nie musisz ponownie wywoływać komendy npm init -y. Podobnie będzie w sytuacji, gdy będziesz zakładać nowy projekt, kopiując z poprzedniego  plik package.json, aby nie musieć przeprowadzać ponownej konfiguracji. To, co musisz natomiast zrobić w takich przypadkach, to zainstalować wszystkie pakiety, których lista znajduje się w pliku package.json. W tym celu wystarczy uruchomić komendę npm install.

W pliku package.json, nad taskiem test, stwórz task init-project. Wykorzystaj w nim komendę npm install. Sekcja scripts powinna wyglądać tak, jak poniżej:

image

Stworzenie katalogów

Stworzenie struktury katalogów nie będzie dla nas wyzwaniem. Znasz już komendę mkdir, ale w tym przypadku zamiast niej wykorzystamy pakiet mkdirp. Zależy nam bowiem na tym, aby ten task nie nadpisywał żadnych plików. Uchronimy się w ten sposób przed problemami w przypadku uruchomienia taska w projekcie, który nie jest pusty.

Na początku zainstaluj w folderze projektu pakiet mkdirp za pomocą komendy npm install mkdirp --save-dev.

W pliku package.json, nad taskiem test, stwórz subtask init:dirs. Tak właśnie będziemy zapisywać nazwy subtasków: słowo-klucz (w tym przypadku init), dwukropek i słowo wskazujące, za co odpowiada dany subtask. Całą nazwę naszego subtaska możemy rozwinąć do initialize directories, czyli zainicjuj katalogi. W subtasku wywołamy komendę mkdirp sass css vendor images js. Całość będzie wyglądała następująco:

image

Jak widzisz, komenda działa bardzo prosto: po słowie mkdirp podajemy po prostu nazwy folderów, które mają zostać założone. Możesz modyfikować ten task na potrzeby innych projektów, podając nazwy potrzebnych katalogów.

Zwróć przy okazji uwagę, że na końcu każdej linii w pliku package.json, oprócz ostatniej, stawiamy przecinek.

Stworzenie plików

Czas na komendę, która utworzy nam kilka pustych plików, dzięki czemu nie będziemy musieli robić tego ręcznie za każdym razem. Tutaj z pomocą przyjdzie nam znana Ci komenda touch.

W pliku packages.json, pod poprzednim subtaskiem, utwórz kolejny: init:files. Umieść w nim następujące wywołanie: touch README.md index.html sass/style.scss js/script.js.

image

Tutaj również nie ma większej filozofii: po komendzie touch podajemy nazwy plików, które mają zostać stworzone. Ten task także bez problemu dasz radę zmodyfikować, gdy jakiś projekt będzie wymagał innego zestawu plików.

Pobranie pliku .gitignore

Plik .gitignore pobierzemy z internetu (dokładnie z szablonowego pliku .gitignore) za pomocą bardzo użytecznej komendy curl. Stwórz kolejny subtask, init:gitignore, z wywołaniem curl https://raw.githubusercontent.com/github/gitignore/master/Node.gitignore -o .gitignore.

Struktura tej komendy jest następująca: najpierw podajemy ścieżkę do pliku, który chcemy pobrać, następnie wstawiamy flagę -o, za pomocą której możemy zmienić nazwę pliku, a na końcu podajemy nazwę, pod którą pobrany plik ma się zapisać na dysku. Tym sposobem plik Node.gitignore zapisuje się w naszym projekcie jako po prostu .gitignore.

image

Możesz używać tej samej struktury dla każdego innego zewnętrznego pliku, którego będzie wymagał Twój projekt.

Składając wszystko w całość

Tak jak wspomnieliśmy na początku, wszystkie nasze subtaski będzie uruchamiał task init-project. Subtaski mogą uruchamiać się sekwencyjnie, czyli jeden po drugim. W takim przypadku możemy wykorzystać łącznik &&.

Zmodyfikuj task init-project, aby po komendzie npm install wywołać wszystkie subtaski, których nazwa zaczyna się od init::

image

Zauważ, że w NPM każdy task i subtask uruchamiamy za pomocą komendy run, używając następującej struktury: npm run nazwa-taska.

Nasz pierwszy task jest gotowy! Przetestujemy go w nowym projekcie: stwórz folder test-init-project i skopiuj do niego plik package.json z projektu task-runner. Następnie w folderze test-init-project uruchom komendę npm run init-project. W konsoli zobaczysz, jak task init-project uruchamia po kolei wszystkie stworzone subtaski.

Po pomyślnym zakończeniu komendy sprawdź, czy w folderze test-init-project utworzyły się potrzebne katalogi i pliki (w tym katalog node_modules, gdzie trzymane są pakiety NPM). Jeżeli tak się stało, możesz skasować folder test-init-project i powrócić do projektu task-runner.

Optymalizacja taska

Task init-project działa, ale jego komenda jest bardzo długa: npm install && npm run init:dirs && npm run init:files && npm run init:gitignore. Czy nie można sprawić, żeby wyglądała bardziej estetycznie i czytelnie? Oczywiście można. Zamiast nakazywać taskowi: "uruchom subtask init:npm-install, potem uruchom subtask init:dirs, potem uruchom subtask init:files" i tak dalej, możemy wydać krótkie polecenie: "uruchom po kolei wszystkie subtaski, których nazwy zaczynają się od init:".

Aby to osiągnąć, będziemy potrzebowali jeszcze jednego pakietu: npm-run-all. Zainstaluj go w projekcie za pomocą komendy npm install npm-run-all --save-dev.

Następnie zmodyfikuj task init-project do następującej postaci:

image

Zauważ, że w komendzie użyliśmy znaku asteriska (gwiazdki), który w tym kontekście oznacza dowolny ciąg znaków po frazie init:. Przy okazji zwróć uwagę, że zadanie npm-install musi zostać wywołane "jawnie" i jako pierwsze. npm-install instaluje nam bowiem potrzebne pakiety NPM, w tym npm-run-all, więc musimy wywołać tę komendę zanim odpalimy npm-run-all.

Zrobione!

Task 2: testowanie plików

W tym tasku dodamy tylko jeden subtask, który będzie testował pliki HTML w naszym projekcie. Jeżeli w przyszłości zechcesz rozbudować swój task runner np. o testy plików CSS czy JS, zrobisz to bardzo prosto, instalując potrzebne pakiety i dodając kolejne subtaski.

Do poprawnego działania tego subtaska będziemy potrzebować pakietu html-validate.

Zainstaluj go w projekcie task-runner, jak zwykle z flagą --save-dev.

Następnie w pliku package.json, pod taskiem test, dodaj subtask test:html i umieść w nim komendę html-validate *.html. Tak samo, jak w poprzednim tasku, asterisk oznacza "dowolny ciąg znaków" - w tym przypadku, dowolny plik z rozszerzeniem .html.

Na końcu zmień task test (kasując uprzednio jego domyślną zawartość), aby wywoływał nasz subtask test:html:

image

Pamiętaj o przecinkach!

Przy każdym dodaniu lub usunięciu taska, musisz pamiętać o sprawdzeniu przecinków. Na końcu każdej linii stawiamy przecinek. Wyjątkiem jest ostatni element zbioru, w naszym przypadku ostatni task, po którym nie stawiamy przecinka.

Aby przygotować swój task na przyjęcie w przyszłości kolejnych subtasków z prefiksem test:, tutaj również możemy zmodyfikować jego postać tak, by używała komendy npm-run-all. Czy domyślasz się, jak to zrobić?

Task 3: generowanie wersji produkcyjnej

Zajmiemy się teraz taskiem build, który będzie odpowiedzialny za przygotowanie plików projektu w wersji gotowej do opublikowania. Jak pamiętasz ze schematu na początku tego modułu, będzie to wymagało kilku kroków:

  • konwersja plików .scss do .css,
  • uruchomienie Autoprefixera,
  • minifikacja pliku .css (usunięcie pustych linii w celu zmniejszenia rozmiaru pliku),
  • przetestowanie poprawności kodu.

Kompilacja .scss do .css i minifikacja

Na chwilę obecną nie mamy jednak zainstalowanego żadnego narzędzia do automatycznej konwersji plików .scss na .css. Na szczęście z pomocą przychodzi nam NPM, który zapewnia potrzebny pakiet: node-sass. Aby go zainstalować, wykonaj w terminalu (w katalogu projektu task-runner) komendę npm install node-sass --save-dev.

Następnie w pliku package.json dodaj nowy subtask, build:sass, z komendą node-sass --output-style compact -o css sass.

Flaga --output-style w tej komendzie jest odpowiedzialna za minifikację pliku CSS, czyli usunięcie pustych linii. Dzięki temu kod CSS będzie nieco bardziej skompresowany, ale nadal czytelny. Jak więc widzisz, komenda załatwia nam od ręki dwie kwestie: kompilację .scss do .css oraz minifikację.

Uruchomienie Autoprefixera

Ten subtask będzie bardzo prosty. Zainstaluj w projekcie pakiet Autoprefixer:

npm install autoprefixer-cli --save-dev

Następnie dodaj subtask build:autoprefixer z komendą autoprefixer-cli css/style.css.

Budujemy build

Czas na pozbieranie wszystkiego w całość. Stwórz task build i po kolei wywołaj w nim wszystkie subtaski build:*, a także task test.

Teraz kiedy uruchomisz w terminalu komendę npm run build, uruchomią się po kolei trzy taski: build:sass, build:autoprefixer oraz test. Z kolei task test uruchamia task test:html.

Całą tę procedurę wywołujemy za pomocą jednej komendy i — co równie ważne — w każdym projekcie będzie to ta sama komenda, niezależnie od zestawu narzędzi używanych w tasku build.

Dodatkowy task build-dev

Zminifikowany plik CSS jest pożądany w wersji produkcyjnej, ale w czasie developowania projektu przyda nam się dostęp do pliku w pełnej wersji, wzbogaconego o mapy źródeł, czyli source maps.

Czym jest source map?

Mapa źródeł, czyli source map, może być tworzona w momencie generowania pliku .css za pomocą prekompilatora, jakim jest Sass. Informuje nas o tym, z której linii, którego pliku źródłowego została wygenerowana dana linijka kodu wynikowego (CSS). Dzięki temu możemy w narzędziach developerskich przeglądarki widzieć, w którym pliku .scss została zapisana reguła dla danego elementu.

image

Jest to bardzo przydatna funkcja w procesie pracy nad projektem i powinna działać automatycznie — jednak przy generowaniu plików do opublikowania na serwerze lepiej nie generować map źródeł.

Wykorzystamy tu znowu node-sass. W tej wersji komenda przyjmie taką postać: node-sass --output-style expanded --source-map true -o css sass. Będziemy potrzebować jej dopiero za chwilę, ale już teraz możesz dodać subtask build-dev:sass z tą komendą.

Ten subtask zbuduje nam pliki .css w wersji developerskiej. Do uruchamiania Autoprefixera wykorzystamy stworzony wcześniej task build:autoprefixer. Pozostaje nam jeszcze dodać task build-dev — wywołaj w nim stworzony przed chwilą subtask build-dev:sass i subtask build:autoprefixer, używając npm-run-all:

image

To tyle na temat budowania wersji produkcyjnej – czas na ostatni task, który będzie wspomagał nas w czasie budowy projektu.

Task 4: bieżąca praca nad projektem

Ten task często jest nazywany watch: obserwuj, co się dzieje w projekcie i podejmuj odpowiednie działania. Zaplanujmy narzędzia, które mają zostać uruchomione:

  • odświeżanie okna przeglądarki po zmianie w kodzie,
  • kompilacja .scss do .css,
  • dodawanie prefiksów w kodzie.

Odświeżanie przeglądarki

Do tego zadania wykorzystamy znany nam już pakiet BrowserSync. Zainstaluj go (z flagą --save-dev) w katalogu projektu, a następnie stwórz dla niego subtask:

"watch:browsersync": "browser-sync start --server --files \"css/*.css\" \"*.html\""

Kompilacja Sassa i Autoprefixer

Do prawidłowego działania tego zadania będziemy potrzebowali dodatkowego pakietu: OnChange. Uzupełni on funkcjonowanie Autoprefixera, który domyślnie nie ma wbudowanej funkcji watch (czyli nie może na bieżąco reagować na zmiany w plikach). Doinstalujmy ten pakiet w folderze projektu za pomocą komendy npm install onchange --save-dev.

Stworzymy teraz jeden subtask, który zrobi za nas dwie rzeczy: będzie uruchamiał OnChange obserwujący pliki w katalogu sass/, a po wykryciu zmiany uruchomi najpierw kompilator Sass, a następnie Autoprefixer. Nadajmy mu nazwę watch:sassprefixer. :) Powinien on wywoływać następującą komendę:

"watch:sassprefixer": "onchange sass/*.scss -- npm run build-dev"

Przyjrzyj się temu subtaskowi i prześledź ścieżkę, którą podąża. Zauważ, że wykorzystaliśmy tutaj stworzony wcześniej subtask build-dev.

Budujemy task watch

Mając to wszystko, możemy złożyć w całość nasz task watch. Chcemy, by na samym początku uruchamiał on task build. Jest to dobra praktyka, do której warto się stosować. Już na tym etapie pomoże nam to uniknąć błędów, ponieważ task build uruchamia task test, więc unikniemy sytuacji, gdy o jakimś błędzie dowiemy się dopiero po zakończeniu prac nad projektem. W przyszłości możesz dodać do niego więcej zadań, które będą wykonywać inne operacje potrzebne do prawidłowego działania Twojej strony.

Bezpośrednio po zbudowaniu wersji produkcyjnej, będziemy chcieli ponownie zbudować style, tym razem jednak z wykorzystaniem taska build-dev. Dzięki temu, po uruchomieniu taska watch, będziemy mieli zbudowaną wersję developerską styli.

Następnie watch powinien uruchamiać subtaski watch:sassprefixer i npm run watch:browsersync. Wykorzystamy tutaj znów npm-run-all, tym razem z flagą -p (skrót od flagi --parallel). Pozwala na uruchamianie innych tasków w trybie równoległym, czyli tak, jakby każdy z nich był uruchomiony w osobnym oknie terminala:

image

Task watch gotowy!

Podsumowanie

Gratulacje! Oto Twój pierwszy profesjonalny task runner. Możesz teraz swobodnie rozszerzać go o inne pakiety i rozbudowywać go wedle woli. Stworzona przed chwilą wersja powinna Ci jednak spokojnie wystarczyć do wielu projektów HTML/CSS/JS.

Poniżej zamieszczamy pełny kod pliku package.json stworzonego w tym module:

{
  "name": "taskrunner",
  "version": "1.0.0",
  "description": "",
  "main": "index.html",
  "scripts": {
    "init-project": "npm install && npm-run-all init:*",

    "init:dirs": "mkdirp sass css vendor images js",
    "init:files": "touch README.md index.html sass/style.scss js/script.js",
    "init:gitignore": "curl https://raw.githubusercontent.com/github/gitignore/master/Node.gitignore -o .gitignore",

    "test": "npm run test:html",
    "test:html": "html-validate *.html",

    "build": "npm-run-all build:* test",
    "build:sass": "node-sass --output-style compact -o css sass",
    "build:autoprefixer": "autoprefixer-cli css/style.css",

    "build-dev": "npm-run-all build-dev:sass build:autoprefixer",
    "build-dev:sass": "node-sass --output-style expanded --source-map true -o css sass",

    "watch": "npm-run-all build:* build-dev -p watch:*",
    "watch:browsersync": "browser-sync start --server --files \"css/*.css\" \"*.html\"",
    "watch:sassprefixer": "onchange sass/*.scss -- npm run build-dev"
  },
  "keywords": [],
  "author": "",
  "license": "ISC",
  "dependencies": {},
  "devDependencies": {
    "autoprefixer-cli": "^1.0.0",
    "browser-sync": "^2.26.3",
    "mkdirp": "^0.5.1",
    "node-sass": "^4.11.0",
    "npm-run-all": "^4.1.5",
    "html-validate": "^2.8.0",
    "onchange": "^5.2.0"
  }
}

Użyjesz go już za moment w miniprojekcie!

Zadanie: projekt z task runnerem

W tym miniprojekcie zakodujesz prosty landing page, używając task runnera i Gita.

Pamiętaj, aby od początku poprawnie nazywać commity i trzymać się dobrych praktyk użycia Gita.

Twoim zadaniem jest:

  1. Utworzenie nowego projektu i zainicjalizowanie w nim Gita.
  2. Umieszczenie w katalogu projektu pliku package.json z modułu powyżej.
  3. Uruchomienie task runnera komendą npm run init-project, a następnie trybu watch komendą npm run watch.
  4. Zakodowanie layoutu na podstawie grafiki (linki poniżej).
  5. Uzupełnienie treści — mogą to być "wypełniacze", np. z Lipsum lub LoremPixel.
  6. Zachowanie dobrych praktyk przedstawionych w dotychczasowych treściach.
  7. Przystosowanie strony do odpowiedniego wyświetlania na urządzeniach mobilnych (RWD).

Pamiętaj, że wszystkie style umieszczasz w pliku sass/style.scss (nawet jeżeli piszesz w konwencji CSS)! Do formatu .css ma je przekształcić Twój task runner.

Do projektu możesz podłączyć grid Bootstrapa (kliknij, aby pobrać paczkę z plikiem CSS) - umieść go w katalogu vendor/ i podepnij w pliku HTML przed plikiem style.css. Grid daje Ci możliwość korzystania ze stylów Bootstrapa dla klas container, container-fluid, row, kolumn (ze wszystkimi klasami responsywnymi, np. col-sm-, col-md-, etc.) oraz z offsetu, ale nie zawiera innych komponentów ani klas pomocniczych. Nie podłączaj całego Bootstrapa — stwórz poprawną strukturę za pomocą grida, a elementy ostyluj własnoręcznie.

Możesz pobrać design strony w formacie:

Z życia developera: framework a zgodność z designem

Czasem bywa tak, że klient przychodzący z projektem do zakodowania życzy sobie, by użyć konkretnego frameworka HTML/CSS, na przykład Bootstrapa. W czasie pracy developer stwierdza jednak, że design nie pasuje do grida (np. elementy nie są takiej szerokości, jak bootstrapowe kolumny). Co wtedy? Trzeba sobie radzić. Wielu klientów przystaje na taką umowę, że developer użyje frameworka, żeby rozmieścić elementy na stronie (np. po trzy w rzędzie), ale gotowa strona nie będzie co do piksela zgodna z projektem graficznym (np. szerokości elementów lub odległości między nimi będą się nieznacznie różnić).

Załóż, że w tym projekcie klient zgodził się na taką opcję. :)

Po skończonej pracy wklej poniżej linka do repozytorium i wyślij Mentorowi.

4.7. Podsumowanie

Udało Ci się przejść cały moduł o narzędziach developerskich – gratulacje! Zdajemy sobie sprawę, że ten moduł mógł być nieco bardziej skomplikowany, niż wcześniejsze. Warto jednak wiedzieć, że współczesny web development opiera się na narzędziach – jeszcze wielokrotnie w czasie swojej drogi spotkasz się z koniecznością obsłużenia kolejnego pakietu, zależności czy frameworka. Umiejętności nabyte w tym module przygotują Cię do wdrożenia się w kolejne narzędzia i lepszego zrozumienia, jak – tak naprawdę – to wszystko działa.

A na razie, mając przygotowany task runner i repozytorium, możesz w miarę możliwości czasowych kodować kolejne projekty i już budować swoje portfolio.

Poniżej zamieszczamy przydatne linki, które pomogą Ci uporządkować wiedzę. Zachęcamy zwłaszcza do ćwiczenia umiejętności obsługi Gita, w tym pracy na branchach i rozwiązywania konfliktów. Najlepiej twórz do tego celu testowe repozytoria, które możesz bez konsekwencji zepsuć. ;)

Pogłębianie znajomości Gita

4.8. Quiz powtórkowy

Na koniec tego modułu przygotowaliśmy dla Ciebie quiz powtórkowy. Pomoże Ci on powtórzyć wiedzę z poprzednich modułów.

Odpowiedzi tego quizu nie są nigdzie zapisywane, więc są tylko do Twojej wiadomości. Ten quiz ma Ci posłużyć jako pomoc w nauce – dlatego pod każdym pytaniem znajdziesz guzik, który sprawdzi poprawność Twoich odpowiedzi oraz poda Ci wyjaśnienie zagadnienia poruszanego w tym pytaniu.

1. Właściwość position: relative; sprawi, że element:

Wyjaśnienie

Przypomnijmy sobie, czym charakteryzują się poszczególne pozycje:

  • static – domyślna pozycja,
  • relative – pozycja elementu będzie ustawiana względem jego pierwotnego położenia,
  • absolute – pozycja ustawiana względem najbliższego rodzica o pozycji innej niż static, a jeśli takowego nie ma, to względem całej strony,
  • fixed – element jest przyklejony do okna i nie przesuwa się przy przewijaniu strony, a jego pozycja jest ustawiana względem okna.

Ponadto, jeśli element ma pozycję absolute lub fixed, to nie zajmuje miejsca na stronie. Innymi słowy, pozostałe elementy na stronie będą zachowywać się tak, jakby tego elementu w ogóle nie było.

2. Zaznacz wszystkie prawdziwe zdania dotyczące media queries (MQ):

Wyjaśnienie

MQ pozwalają na zapisanie bloku kodu CSS, który będzie działał tylko wtedy, kiedy zostaną spełnione określone warunki, np. szerokość i wysokość okna przeglądarki, rozdzielczość, orientację poziomą lub pionową, etc.

Możemy stosować wiele MQ z różnymi warunkami, aby dostosować wygląd strony do różnych urządzeń. W ten sposób możemy m.in. modyfikować działania grida w zależności od szerokości okna – jednak grida możemy używać również bez MQ, np. jeśli strona ma tylko jedną kolumnę i nie potrzebujemy jej dostosowywać za pomocą MQ.

Kod CSS zawarty w MQ nie jest w żaden sposób ważniejszy niż reszta kodu CSS. Oznacza to, że podlega on normalnym zasadom kaskadowości, czyli (w wielkim skrócie) ważniejsza jest ta deklaracja, której selektor jest dokładniejszy, a w przypadku tak samo dokładnych selektorów, ważniejsza będzie deklaracja, która jest niżej w pliku.

3. Viewport to:

Wyjaśnienie

Viewport jest tagiem <meta> o następującej składni:

<meta name="viewport" content="width=device-width, initial-scale=1.0">

Najczęściej nie ma potrzeby jego modyfikacji i można użyć powyższej linii kodu, wstawiając ją w <head> kodu HTML.

4. Klasy container zwykle używa się do:

Wyjaśnienie

Klasa container najczęściej jest stosowana do ograniczenia szerokości oraz poziomego wycentrowania contentu strony.

Nie powinno się jednak ustawiać jej na wrapperze całej zawartości strony, ponieważ takie rozwiązanie bardzo utrudnia późniejsze dodanie sekcji, której tło ma być innego koloru i rozciągnięte na całą szerokość okna.

Z tego względu najlepiej ustawiać klasę container na poszczególnych sekcjach strony lub na wrapperach w ich wnętrzu.

Jeśli nie pamiętasz co znaczy słowo wrapper – pochodzi od angielskiego wrap, czyli zawijać. Popularnie mianem wrappera określa się jakiś element, który okala (zawiera w sobie) inne elementy.

5. Co daje nam używanie Bootstrapa?

Wyjaśnienie

Bootstrap pomaga nam szybko stworzyć ciekawą stronę, za pomocą elementów layoutu wykorzystujących grid, który łatwo możemy dostosować dla RWD. Zawiera on także szereg gotowych komponentów, począwszy od podstawowych (np. guziki czy nagłówki), przez bardziej rozbudowane (np. nawigacje, jumbotrony), aż po interaktywne (np. akordeon, tooltip).

Bootstrap pozwala nam również na dostosowanie jego stylów. Możemy to zrobić, pobierając pliki źródłowe Bootstrapa lub korzystając z formularza pozwalającego na pobranie customowej wersji tego frameworka.

Warto jednak pamiętać, że nadmierne wykorzystywanie Bootstrapa będzie skutkować brakiem trenowania umiejętności tworzenia komponentów od zera. Dlatego gorąco zachęcamy do używania Bootstrapa oszczędnie, szczególnie w trakcie kursu.

;